| 1 |
<?php
|
| 2 |
// $Id: apachesolr_search.module,v 1.1.2.6.2.104 2009/06/22 19:13:13 pwolanin Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Provides a content search implementation for node content for use with the
|
| 7 |
* Apache Solr search application.
|
| 8 |
*/
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Implementation of hook_help().
|
| 12 |
*/
|
| 13 |
function apachesolr_search_help($section) {
|
| 14 |
switch ($section) {
|
| 15 |
case 'admin/settings/apachesolr/index':
|
| 16 |
if (variable_get('apachesolr_read_only', 0)) {
|
| 17 |
return t('Operating in read-only mode; updates are disabled.');
|
| 18 |
}
|
| 19 |
$remaining = 0;
|
| 20 |
$total = 0;
|
| 21 |
// Collect the stats
|
| 22 |
$status = module_invoke('apachesolr_search', 'search', 'status');
|
| 23 |
$remaining += $status['remaining'];
|
| 24 |
$total += $status['total'];
|
| 25 |
|
| 26 |
return t('The search index is generated by !cron. %percentage of the site content has been sent to the server. There @items left to send.', array(
|
| 27 |
'!cron' => l(t('running cron'), 'admin/reports/status/run-cron', array('query' => array('destination' => 'admin/settings/apachesolr/index'))),
|
| 28 |
'%percentage' => ((int)min(100, 100 * ($total - $remaining) / max(1, $total))) .'%',
|
| 29 |
'@items' => format_plural($remaining, t('is 1 item'), t('are @count items')
|
| 30 |
)));
|
| 31 |
}
|
| 32 |
}
|
| 33 |
|
| 34 |
/**
|
| 35 |
* Implementation of hook_menu().
|
| 36 |
*/
|
| 37 |
function apachesolr_search_menu() {
|
| 38 |
$items['admin/settings/apachesolr/query-fields'] = array(
|
| 39 |
'title' => 'Search fields',
|
| 40 |
'page callback' => 'apachesolr_search_settings_page',
|
| 41 |
'access arguments' => array('administer site configuration'),
|
| 42 |
'weight' => 1,
|
| 43 |
'type' => MENU_LOCAL_TASK,
|
| 44 |
'file' => 'apachesolr_search.admin.inc',
|
| 45 |
);
|
| 46 |
$items['admin/settings/apachesolr/content-bias'] = array(
|
| 47 |
'title' => 'Content bias settings',
|
| 48 |
'page callback' => 'apachesolr_boost_settings_page',
|
| 49 |
'access arguments' => array('administer site configuration'),
|
| 50 |
'weight' => 1,
|
| 51 |
'type' => MENU_LOCAL_TASK,
|
| 52 |
'file' => 'apachesolr_search.admin.inc',
|
| 53 |
);
|
| 54 |
|
| 55 |
return $items;
|
| 56 |
}
|
| 57 |
|
| 58 |
/**
|
| 59 |
* Implementation of hook_menu_alter().
|
| 60 |
*/
|
| 61 |
function apachesolr_search_menu_alter(&$menu) {
|
| 62 |
if (isset($menu['search/apachesolr_search/%menu_tail'])) {
|
| 63 |
$menu['search']['page callback'] = 'apachesolr_search_view';
|
| 64 |
$menu['search/apachesolr_search/%menu_tail']['page callback'] = 'apachesolr_search_view';
|
| 65 |
}
|
| 66 |
if (variable_get('apachesolr_search_make_default', 0)) {
|
| 67 |
if (isset($menu['search/node/%menu_tail'])) {
|
| 68 |
// Hide the node search tab.
|
| 69 |
$menu['search/node/%menu_tail']['type'] = MENU_CALLBACK;
|
| 70 |
unset($menu['search/node/%menu_tail']['title callback'], $menu['search/node/%menu_tail']['title arguments']);
|
| 71 |
$menu['search/node/%menu_tail']['title'] = 'Search';
|
| 72 |
}
|
| 73 |
if (isset($menu['search/apachesolr_search/%menu_tail'])) {
|
| 74 |
// Alter the solr search tab
|
| 75 |
$menu['search/apachesolr_search/%menu_tail']['weight'] = -10;
|
| 76 |
unset($menu['search/apachesolr_search/%menu_tail']['title callback'], $menu['search/apachesolr_search/%menu_tail']['title arguments']);
|
| 77 |
$menu['search/apachesolr_search/%menu_tail']['title'] = 'Content';
|
| 78 |
}
|
| 79 |
if (isset($menu['search'])) {
|
| 80 |
$menu['search']['page arguments'] = array('apachesolr_search');
|
| 81 |
}
|
| 82 |
}
|
| 83 |
}
|
| 84 |
|
| 85 |
/**
|
| 86 |
* Implementation of hook_update_index().
|
| 87 |
*/
|
| 88 |
function apachesolr_search_update_index() {
|
| 89 |
$cron_limit = variable_get('apachesolr_cron_limit', 50);
|
| 90 |
$rows = apachesolr_get_nodes_to_index('apachesolr_search', $cron_limit);
|
| 91 |
apachesolr_index_nodes($rows, 'apachesolr_search');
|
| 92 |
}
|
| 93 |
|
| 94 |
/**
|
| 95 |
* Implementation of hook_apachesolr_types_exclude().
|
| 96 |
*/
|
| 97 |
function apachesolr_search_apachesolr_types_exclude($namespace) {
|
| 98 |
if ($namespace == 'apachesolr_search') {
|
| 99 |
$excluded_types = variable_get('apachesolr_search_excluded_types', array());
|
| 100 |
return array_filter($excluded_types);
|
| 101 |
}
|
| 102 |
}
|
| 103 |
|
| 104 |
/**
|
| 105 |
* Implementation of hook_search().
|
| 106 |
*/
|
| 107 |
function apachesolr_search_search($op = 'search', $keys = NULL) {
|
| 108 |
|
| 109 |
switch ($op) {
|
| 110 |
case 'name':
|
| 111 |
return t('Search');
|
| 112 |
|
| 113 |
case 'reset':
|
| 114 |
apachesolr_clear_last_index('apachesolr_search');
|
| 115 |
return;
|
| 116 |
|
| 117 |
case 'status':
|
| 118 |
return apachesolr_index_status('apachesolr_search');
|
| 119 |
|
| 120 |
case 'search':
|
| 121 |
$filters = isset($_GET['filters']) ? $_GET['filters'] : '';
|
| 122 |
$solrsort = isset($_GET['solrsort']) ? $_GET['solrsort'] : '';
|
| 123 |
$page = isset($_GET['page']) ? $_GET['page'] : 0;
|
| 124 |
try {
|
| 125 |
$results = apachesolr_search_execute($keys, $filters, $solrsort, 'search/' . arg(1), $page);
|
| 126 |
return $results;
|
| 127 |
}
|
| 128 |
catch (Exception $e) {
|
| 129 |
watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR);
|
| 130 |
apachesolr_failure(t('Solr search'), $keys);
|
| 131 |
}
|
| 132 |
break;
|
| 133 |
} // switch
|
| 134 |
}
|
| 135 |
|
| 136 |
/**
|
| 137 |
* Re-implementation of search_view().
|
| 138 |
*/
|
| 139 |
function apachesolr_search_view($type = NULL) {
|
| 140 |
// Search form submits with POST but redirects to GET.
|
| 141 |
$results = '';
|
| 142 |
if (!isset($_POST['form_id'])) {
|
| 143 |
if (empty($type)) {
|
| 144 |
// Note: search/X can not be a default tab because it would take on the
|
| 145 |
// path of its parent (search). It would prevent remembering keywords when
|
| 146 |
// switching tabs. This is why we drupal_goto to it from the parent instead.
|
| 147 |
drupal_goto('search/apachesolr_search');
|
| 148 |
}
|
| 149 |
$keys = trim(search_get_keys());
|
| 150 |
$filters = '';
|
| 151 |
if ($type == 'apachesolr_search' && isset($_GET['filters'])) {
|
| 152 |
$filters = trim($_GET['filters']);
|
| 153 |
}
|
| 154 |
// Only perform search if there is non-whitespace search term or filters:
|
| 155 |
if ($keys || $filters) {
|
| 156 |
// Log the search keys:
|
| 157 |
$log = $keys;
|
| 158 |
if ($filters) {
|
| 159 |
$log .= 'filters='. $filters;
|
| 160 |
}
|
| 161 |
watchdog('search', '%keys (@type).', array('%keys' => $log, '@type' => t('Search')), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys));
|
| 162 |
|
| 163 |
// Collect the search results:
|
| 164 |
$results = search_data($keys, $type);
|
| 165 |
|
| 166 |
if ($results) {
|
| 167 |
$results = theme('box', t('Search results'), $results);
|
| 168 |
}
|
| 169 |
else {
|
| 170 |
$results = theme('box', t('Your search yielded no results'), search_help('search#noresults', drupal_help_arg()));
|
| 171 |
}
|
| 172 |
}
|
| 173 |
}
|
| 174 |
// Construct the search form.
|
| 175 |
return drupal_get_form('search_form', NULL, $keys, $type) . $results;
|
| 176 |
}
|
| 177 |
|
| 178 |
/**
|
| 179 |
* Execute a search results based on keyword, filter, and sort strings.
|
| 180 |
*
|
| 181 |
* @throws Exception
|
| 182 |
*/
|
| 183 |
function apachesolr_search_execute($keys, $filters, $solrsort, $base_path = '', $page = 0, $caller = 'apachesolr_search') {
|
| 184 |
// Validate sort parameter
|
| 185 |
// TODO: move this to the query class.
|
| 186 |
if (strlen($solrsort) && preg_match('/^([a-z0-9_]+ (asc|desc)(,)?)+$/i', $solrsort)) {
|
| 187 |
$params['sort'] = $solrsort;
|
| 188 |
}
|
| 189 |
else {
|
| 190 |
$solrsort = '';
|
| 191 |
$params = array();
|
| 192 |
}
|
| 193 |
// This is the object that knows about the query coming from the user.
|
| 194 |
$query = apachesolr_drupal_query($keys, $filters, $solrsort, $base_path);
|
| 195 |
if (empty($query)) {
|
| 196 |
throw new Exception(t('Could not construct a Solr query in function apachesolr_search_search()'));
|
| 197 |
}
|
| 198 |
// This is the object that does the communication with the solr server.
|
| 199 |
$solr = apachesolr_get_solr();
|
| 200 |
$params += apachesolr_search_basic_params($query);
|
| 201 |
if ($keys) {
|
| 202 |
$params += apachesolr_search_highlighting_params($query);
|
| 203 |
$params += apachesolr_search_spellcheck_params($query);
|
| 204 |
}
|
| 205 |
else {
|
| 206 |
// No highlighting, use the teaser as a snippet.
|
| 207 |
$params['fl'] .= ',teaser';
|
| 208 |
}
|
| 209 |
apachesolr_search_add_facet_params($params, $query);
|
| 210 |
apachesolr_search_add_boost_params($params, $query, $solr);
|
| 211 |
|
| 212 |
$params['start'] = $page * $params['rows'];
|
| 213 |
|
| 214 |
// Cache the built query. Since all the built queries go through
|
| 215 |
// this process, all the hook_invocations will happen later
|
| 216 |
apachesolr_current_query($query);
|
| 217 |
|
| 218 |
// This hook allows modules to modify the query and params objects.
|
| 219 |
apachesolr_modify_query($query, $params, $caller);
|
| 220 |
if (!$query) {
|
| 221 |
return array();
|
| 222 |
}
|
| 223 |
|
| 224 |
if ('' == $keys) {
|
| 225 |
// Move the fq params to the q.alt for better performance.
|
| 226 |
$params['q.alt'] = implode(' ', $params['fq']);
|
| 227 |
unset($params['fq']);
|
| 228 |
}
|
| 229 |
|
| 230 |
$response = $solr->search($query->get_query_basic(), $params['start'], $params['rows'], $params);
|
| 231 |
// The response is cached so that it is accessible to the blocks and anything
|
| 232 |
// else that needs it beyond the initial search.
|
| 233 |
apachesolr_static_response_cache($response);
|
| 234 |
apachesolr_has_searched(TRUE);
|
| 235 |
// Add search terms and filters onto the breadcrumb.
|
| 236 |
drupal_set_breadcrumb(array_merge(menu_get_active_breadcrumb(), $query->get_breadcrumb()));
|
| 237 |
return apachesolr_process_response($response, $query, $params);
|
| 238 |
}
|
| 239 |
|
| 240 |
function apachesolr_search_basic_params($query) {
|
| 241 |
$params = array(
|
| 242 |
'fl' => 'id,nid,title,comment_count,type,created,changed,score,path,url,uid,name',
|
| 243 |
'rows' => variable_get('apachesolr_rows', 10),
|
| 244 |
'facet' => 'true',
|
| 245 |
'facet.mincount' => 1,
|
| 246 |
'facet.sort' => 'true'
|
| 247 |
);
|
| 248 |
return $params;
|
| 249 |
}
|
| 250 |
|
| 251 |
/**
|
| 252 |
* Add highlighting settings to the search params.
|
| 253 |
*
|
| 254 |
* These settings are set in solrconfig.xml.
|
| 255 |
* See the defaults there.
|
| 256 |
* If you wish to override them, you can via settings.php
|
| 257 |
*/
|
| 258 |
function apachesolr_search_highlighting_params($query) {
|
| 259 |
$params['hl'] = variable_get('apachesolr_hl_active', NULL);
|
| 260 |
$params['hl.fragsize']= variable_get('apachesolr_hl_textsnippetlength', NULL);
|
| 261 |
$params['hl.simple.pre'] = variable_get('apachesolr_hl_pretag', NULL);
|
| 262 |
$params['hl.simple.post'] = variable_get('apachesolr_hl_posttag', NULL);
|
| 263 |
$params['hl.snippets'] = variable_get('apachesolr_hl_numsnippets', NULL);
|
| 264 |
$params['hl.fl'] = variable_get('apachesolr_hl_fieldtohightlight', NULL);
|
| 265 |
return $params;
|
| 266 |
}
|
| 267 |
|
| 268 |
function apachesolr_search_spellcheck_params($query) {
|
| 269 |
$params = array();
|
| 270 |
if (variable_get('apachesolr_search_spellcheck', FALSE)) {
|
| 271 |
//Add new parameter to the search request
|
| 272 |
$params['spellcheck.q'] = $query->get_query_basic();
|
| 273 |
$params['spellcheck'] = 'true';
|
| 274 |
}
|
| 275 |
return $params;
|
| 276 |
}
|
| 277 |
|
| 278 |
function apachesolr_search_add_facet_params(&$params, $query) {
|
| 279 |
$facet_query_limits = variable_get('apachesolr_facet_query_limits', array());
|
| 280 |
$facet_missing = variable_get('apachesolr_facet_missing', array());
|
| 281 |
|
| 282 |
foreach (apachesolr_get_enabled_facets() as $module => $module_facets) {
|
| 283 |
foreach($module_facets as $delta => $facet_field) {
|
| 284 |
// TODO: generalize handling of date and range facets.
|
| 285 |
if ($module == 'apachesolr_search' && ($facet_field == 'created' || $facet_field == 'changed')) {
|
| 286 |
list($start, $end, $gap) = apachesolr_search_date_range($query, $facet_field);
|
| 287 |
if ($gap) {
|
| 288 |
$params['facet.date'][] = $facet_field;
|
| 289 |
$params['f.'. $facet_field .'.facet.date.start'] = $start;
|
| 290 |
$params['f.'. $facet_field .'.facet.date.end'] = $end;
|
| 291 |
$params['f.'. $facet_field .'.facet.date.gap'] = $gap;
|
| 292 |
}
|
| 293 |
}
|
| 294 |
else {
|
| 295 |
$params['facet.field'][] = $facet_field;
|
| 296 |
// Facet limits
|
| 297 |
if (isset($facet_query_limits[$module][$delta])) {
|
| 298 |
$params['f.' . $facet_field . '.facet.limit'] = $facet_query_limits[$module][$delta];
|
| 299 |
}
|
| 300 |
// Facet missing
|
| 301 |
if (!empty($facet_missing[$module][$delta])) {
|
| 302 |
$params['f.' . $facet_field . '.facet.missing'] = 'true';
|
| 303 |
}
|
| 304 |
}
|
| 305 |
}
|
| 306 |
}
|
| 307 |
|
| 308 |
if (!empty($params['facet.field'])) {
|
| 309 |
// Add a default limit for fields where no limit was set.
|
| 310 |
$params['facet.limit'] = variable_get('apachesolr_facet_query_limit_default', 20);
|
| 311 |
}
|
| 312 |
}
|
| 313 |
|
| 314 |
function apachesolr_search_add_boost_params(&$params, $query, $solr) {
|
| 315 |
// Note - we have query fields set in solrconfig.xml, which will operate when
|
| 316 |
// none are set.
|
| 317 |
$qf = variable_get('apachesolr_search_query_fields', array());
|
| 318 |
$fields = $solr->getFields();
|
| 319 |
if ($qf && $fields) {
|
| 320 |
foreach ($fields as $field_name => $field) {
|
| 321 |
if (!empty($qf[$field_name])) {
|
| 322 |
if ($field_name == 'body') {
|
| 323 |
// Body is the only normed field.
|
| 324 |
$qf[$field_name] *= 40.0;
|
| 325 |
}
|
| 326 |
$params['qf'][] = $field_name . '^'. $qf[$field_name];
|
| 327 |
}
|
| 328 |
}
|
| 329 |
}
|
| 330 |
|
| 331 |
$data = $solr->getLuke();
|
| 332 |
if (isset($data->index->numDocs)) {
|
| 333 |
$total = $data->index->numDocs;
|
| 334 |
}
|
| 335 |
else {
|
| 336 |
$total = db_result(db_query("SELECT COUNT(nid) FROM {node}"));
|
| 337 |
}
|
| 338 |
// For the boost functions for the created timestamp, etc we use the
|
| 339 |
// standard date-biasing function, as suggested (but steeper) at
|
| 340 |
// http://wiki.apache.org/solr/DisMaxRequestHandler
|
| 341 |
// rord() returns 1 for the newset doc, and the number in the index for
|
| 342 |
// the oldest doc. The function is thus: $total/(rord()*$steepness + $total).
|
| 343 |
$date_settings = variable_get('apachesolr_search_date_boost', '4:200.0');
|
| 344 |
list($date_steepness, $date_boost) = explode(':', $date_settings);
|
| 345 |
if ($date_boost) {
|
| 346 |
$params['bf'][] = "recip(rord(created),$date_steepness,$total,$total)^$date_boost";
|
| 347 |
}
|
| 348 |
// Boost on comment count.
|
| 349 |
$comment_settings = variable_get('apachesolr_search_comment_boost', '0:0');
|
| 350 |
list($comment_steepness, $comment_boost) = explode(':', $comment_settings);
|
| 351 |
if ($comment_boost) {
|
| 352 |
$params['bf'][] = "recip(rord(comment_count),$comment_steepness,$total,$total)^$comment_boost";
|
| 353 |
}
|
| 354 |
// Boost for a more recent comment or node edit.
|
| 355 |
$changed_settings = variable_get('apachesolr_search_changed_boost', '0:0');
|
| 356 |
list($changed_steepness, $changed_boost) = explode(':', $changed_settings);
|
| 357 |
if ($changed_boost) {
|
| 358 |
$params['bf'][] = "recip(rord(last_comment_or_change),$changed_steepness,$total,$total)^$changed_boost";
|
| 359 |
}
|
| 360 |
// Boost for nodes with sticky bit set.
|
| 361 |
$sticky_boost = variable_get('apachesolr_search_sticky_boost', 0);
|
| 362 |
if ($sticky_boost) {
|
| 363 |
$params['bq'][] = "sticky:true^$sticky_boost";
|
| 364 |
}
|
| 365 |
// Boost for nodes with promoted bit set.
|
| 366 |
$promote_boost = variable_get('apachesolr_search_promote_boost', 0);
|
| 367 |
if ($promote_boost) {
|
| 368 |
$params['bq'][] = "promote:true^$promote_boost";
|
| 369 |
}
|
| 370 |
// Modify the weight of results according to the node types.
|
| 371 |
$type_boosts = variable_get('apachesolr_search_type_boosts', array());
|
| 372 |
if (!empty($type_boosts)) {
|
| 373 |
foreach ($type_boosts as $type => $boost) {
|
| 374 |
// Only add a param if the boost is != 0 (i.e. > "Normal").
|
| 375 |
if ($boost) {
|
| 376 |
$params['bq'][] = "type:$type^$boost";
|
| 377 |
}
|
| 378 |
}
|
| 379 |
}
|
| 380 |
}
|
| 381 |
|
| 382 |
function apachesolr_process_response($response, $query, $params) {
|
| 383 |
$results = array();
|
| 384 |
// We default to getting snippets from the body.
|
| 385 |
$hl_fl = is_null($params['hl.fl']) ? 'body' : $params['hl.fl'];
|
| 386 |
$total = $response->response->numFound;
|
| 387 |
pager_query("SELECT %d", $params['rows'], 0, NULL, $total);
|
| 388 |
if ($total > 0) {
|
| 389 |
foreach ($response->response->docs as $doc) {
|
| 390 |
$extra = array();
|
| 391 |
|
| 392 |
// Find the nicest available snippet.
|
| 393 |
if (isset($response->highlighting->{$doc->id}->$hl_fl)) {
|
| 394 |
$snippet = theme('apachesolr_search_snippets', $doc, $response->highlighting->{$doc->id}->$hl_fl);
|
| 395 |
}
|
| 396 |
elseif (isset($doc->teaser)) {
|
| 397 |
$snippet = theme('apachesolr_search_snippets', $doc, array(truncate_utf8($doc->teaser, 256, TRUE)));
|
| 398 |
}
|
| 399 |
else {
|
| 400 |
$snippet = '';
|
| 401 |
}
|
| 402 |
|
| 403 |
if (!isset($doc->body)) {
|
| 404 |
$doc->body = $snippet;
|
| 405 |
}
|
| 406 |
$doc->created = strtotime($doc->created);
|
| 407 |
$doc->changed = strtotime($doc->changed);
|
| 408 |
// Allow modules to alter each document.
|
| 409 |
drupal_alter('apachesolr_search_result', $doc);
|
| 410 |
// Copy code from comment_nodeapi().
|
| 411 |
$extra[] = format_plural($doc->comment_count, '1 comment', '@count comments');
|
| 412 |
$results[] = array(
|
| 413 |
'link' => url($doc->path),
|
| 414 |
'type' => apachesolr_search_get_type($doc->type),
|
| 415 |
'title' => $doc->title,
|
| 416 |
'user' => theme('username', $doc),
|
| 417 |
'date' => $doc->created,
|
| 418 |
'node' => $doc,
|
| 419 |
'extra' => $extra,
|
| 420 |
'score' => $doc->score,
|
| 421 |
'snippet' => $snippet,
|
| 422 |
);
|
| 423 |
}
|
| 424 |
|
| 425 |
// Hook to allow modifications of the retrieved results
|
| 426 |
foreach (module_implements('apachesolr_process_results') as $module) {
|
| 427 |
$function = $module .'_apachesolr_process_results';
|
| 428 |
$function($results);
|
| 429 |
}
|
| 430 |
}
|
| 431 |
return $results;
|
| 432 |
}
|
| 433 |
|
| 434 |
function apachesolr_search_date_range($query, $facet_field) {
|
| 435 |
foreach ($query->get_filters($facet_field) as $filter) {
|
| 436 |
// If we had an ISO date library we could use ISO dates
|
| 437 |
// directly. Instead, we convert to Unix timestamps for comparison.
|
| 438 |
// Only use dates if we are able to parse into timestamps.
|
| 439 |
$start = strtotime($filter['#start']);
|
| 440 |
$end = strtotime($filter['#end']);
|
| 441 |
if ($start && $end && ($start < $end)) {
|
| 442 |
$start_iso = $filter['#start'];
|
| 443 |
$end_iso = $filter['#end'];
|
| 444 |
// Determine the drilldown gap for this range.
|
| 445 |
$gap = apachesolr_date_gap_drilldown(apachesolr_date_find_query_gap($start_iso, $end_iso));
|
| 446 |
}
|
| 447 |
}
|
| 448 |
// If there is no $delta field in query object, get initial
|
| 449 |
// facet.date.* params from the DB and determine the best search
|
| 450 |
// gap to use. This callback assumes $delta is 'changed' or 'created'.
|
| 451 |
if (!isset($start_iso)) {
|
| 452 |
$start_iso = apachesolr_date_iso(db_result(db_query("SELECT MIN($facet_field) FROM {node} WHERE status = 1")));
|
| 453 |
$end_iso = apachesolr_date_iso(db_result(db_query("SELECT MAX($facet_field) FROM {node} WHERE status = 1")));
|
| 454 |
$gap = apachesolr_date_determine_gap($start_iso, $end_iso);
|
| 455 |
}
|
| 456 |
// Return a query range from the beginning of a gap period to the beginning
|
| 457 |
// of the next gap period. We ALWAYS generate query ranges of this form
|
| 458 |
// and the apachesolr_date_*() helper functions require it.
|
| 459 |
return array("$start_iso/$gap", "$end_iso+1$gap/$gap", "+1$gap");
|
| 460 |
}
|
| 461 |
|
| 462 |
/**
|
| 463 |
* Implementation of hook_apachesolr_facets().
|
| 464 |
*
|
| 465 |
* Returns an array keyed by block delta.
|
| 466 |
*/
|
| 467 |
function apachesolr_search_apachesolr_facets() {
|
| 468 |
$facets = array();
|
| 469 |
|
| 470 |
$facets['type'] = array(
|
| 471 |
'info' => t('Apache Solr Search: Filter by content type'),
|
| 472 |
'facet_field' => 'type',
|
| 473 |
);
|
| 474 |
$facets['uid'] = array(
|
| 475 |
'info' => t('Apache Solr Search: Filter by author'),
|
| 476 |
'facet_field' => 'uid',
|
| 477 |
);
|
| 478 |
$facets['language'] = array(
|
| 479 |
'info' => t('Apache Solr Search: Filter by language'),
|
| 480 |
'facet_field' => 'language',
|
| 481 |
);
|
| 482 |
|
| 483 |
$facets['changed'] = array(
|
| 484 |
'info' => t('Apache Solr Search: Filter by updated date'),
|
| 485 |
'facet_field' => 'changed',
|
| 486 |
);
|
| 487 |
$facets['created'] = array(
|
| 488 |
'info' => t('Apache Solr Search: Filter by post date'),
|
| 489 |
'facet_field' => 'created',
|
| 490 |
);
|
| 491 |
|
| 492 |
// A book module facet.
|
| 493 |
if (module_exists('book')) {
|
| 494 |
$facets['is_book_bid'] = array(
|
| 495 |
'info' => t('Apache Solr Search: Filter by Book'),
|
| 496 |
'facet_field' => 'is_book_bid',
|
| 497 |
);
|
| 498 |
}
|
| 499 |
|
| 500 |
// Get taxonomy vocabulary facets.
|
| 501 |
if (module_exists('taxonomy')) {
|
| 502 |
$vocabs = taxonomy_get_vocabularies();
|
| 503 |
foreach ($vocabs as $vid => $vocab) {
|
| 504 |
// In this case the delta and facet field are the same.
|
| 505 |
$delta = 'im_vid_' . $vid;
|
| 506 |
$facets[$delta] = array(
|
| 507 |
'info' => t('Apache Solr Search: Filter by taxonomy @name', array('@name' => $vocab->name)),
|
| 508 |
'facet_field' => $delta,
|
| 509 |
);
|
| 510 |
}
|
| 511 |
}
|
| 512 |
|
| 513 |
// Get CCK field facets.
|
| 514 |
$fields = apachesolr_cck_fields();
|
| 515 |
if ($fields) {
|
| 516 |
foreach ($fields as $name => $field) {
|
| 517 |
// $delta can only be 32 chars, and the CCK field name may be this
|
| 518 |
// long also, so we cannot add anything to it.
|
| 519 |
$facets[$field['field_name']] = array(
|
| 520 |
'info' => t('Apache Solr Search: Filter by @field', array('@field' => $field['label'])),
|
| 521 |
'facet_field' => apachesolr_index_key($field),
|
| 522 |
);
|
| 523 |
}
|
| 524 |
}
|
| 525 |
return $facets;
|
| 526 |
}
|
| 527 |
|
| 528 |
/**
|
| 529 |
* Implementation of hook_block().
|
| 530 |
*/
|
| 531 |
function apachesolr_search_block($op = 'list', $delta = 0, $edit = array()) {
|
| 532 |
|
| 533 |
switch ($op) {
|
| 534 |
case 'list':
|
| 535 |
$enabled_facets = apachesolr_get_enabled_facets('apachesolr_search');
|
| 536 |
$facets = apachesolr_search_apachesolr_facets();
|
| 537 |
// Add the blocks
|
| 538 |
$blocks = array();
|
| 539 |
foreach ($enabled_facets as $delta => $facet_field) {
|
| 540 |
if (isset($facets[$delta])) {
|
| 541 |
$blocks[$delta] = $facets[$delta] + array('cache' => BLOCK_CACHE_PER_PAGE,);
|
| 542 |
}
|
| 543 |
}
|
| 544 |
$blocks['currentsearch'] = array(
|
| 545 |
'info' => t('Apache Solr Search: Current search'),
|
| 546 |
'cache' => BLOCK_CACHE_PER_PAGE,
|
| 547 |
);
|
| 548 |
return $blocks;
|
| 549 |
|
| 550 |
case 'view':
|
| 551 |
if (apachesolr_has_searched()) {
|
| 552 |
// Get the query and response. Without these no blocks make sense.
|
| 553 |
$response = apachesolr_static_response_cache();
|
| 554 |
if (empty($response)) {
|
| 555 |
return;
|
| 556 |
}
|
| 557 |
$query = apachesolr_current_query();
|
| 558 |
|
| 559 |
$facets = apachesolr_get_enabled_facets('apachesolr_search');
|
| 560 |
if (empty($facets[$delta]) && ($delta != 'currentsearch')) {
|
| 561 |
return;
|
| 562 |
}
|
| 563 |
|
| 564 |
// Get information needed by the taxonomy blocks about limits.
|
| 565 |
$initial_limits = variable_get('apachesolr_facet_query_initial_limits', array());
|
| 566 |
$limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10);
|
| 567 |
|
| 568 |
// Handle taxonomy vocabulary facets
|
| 569 |
if ((strpos($delta, 'im_vid_') === 0) && module_exists('taxonomy')) {
|
| 570 |
|
| 571 |
if (is_object($response->facet_counts->facet_fields->$delta)) {
|
| 572 |
$contains_active = FALSE;
|
| 573 |
$terms = array();
|
| 574 |
|
| 575 |
foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) {
|
| 576 |
$options = array();
|
| 577 |
if ($tid == '_empty_') {
|
| 578 |
// TODO - for now we don't handle facet missing.
|
| 579 |
continue;
|
| 580 |
}
|
| 581 |
$unclick_link = '';
|
| 582 |
unset($active);
|
| 583 |
$term = taxonomy_get_term($tid);
|
| 584 |
$new_query = clone $query;
|
| 585 |
if ($active = $query->has_filter('tid', $tid)) {
|
| 586 |
$contains_active = TRUE;
|
| 587 |
$new_query->remove_filter('tid', $term->tid);
|
| 588 |
$options['query'] = $new_query->get_url_querystring();
|
| 589 |
$link = theme('apachesolr_unclick_link', $term->name, $new_query->get_path(), $options);
|
| 590 |
}
|
| 591 |
else {
|
| 592 |
$new_query->add_filter('tid', $term->tid);
|
| 593 |
$options['query'] = $new_query->get_url_querystring();
|
| 594 |
$link = theme('apachesolr_facet_link', $term->name, $new_query->get_path(), $options, $count, $active, $response->response->numFound);
|
| 595 |
}
|
| 596 |
$countsort = $count == 0 ? '' : 1 / $count;
|
| 597 |
// if numdocs == 1 and !active, don't add.
|
| 598 |
if ($response->response->numFound > 1 || $active) {
|
| 599 |
$terms[$term->vid][$active ? $countsort . $term->name : 1 + $countsort . $term->name] = $link;
|
| 600 |
}
|
| 601 |
}
|
| 602 |
}
|
| 603 |
$vid = substr($delta, 7);
|
| 604 |
$vocab = taxonomy_vocabulary_load($vid);
|
| 605 |
if (is_numeric($vid) && is_array($terms) && isset($terms[$vid]) && is_array($terms[$vid])) {
|
| 606 |
ksort($terms[$vid]);
|
| 607 |
$limit = isset($initial_limits['apachesolr_search'][$delta]) ? $initial_limits['apachesolr_search'][$delta] : $limit_default;
|
| 608 |
return array(
|
| 609 |
'subject' => t('Filter by @name', array('@name' => $vocab->name)),
|
| 610 |
'content' => theme('apachesolr_facet_list', $terms[$vid], $limit),
|
| 611 |
);
|
| 612 |
}
|
| 613 |
return;
|
| 614 |
}
|
| 615 |
|
| 616 |
switch ($delta) {
|
| 617 |
case 'currentsearch':
|
| 618 |
$fields = $query->get_filters();
|
| 619 |
$path = $query->get_path();
|
| 620 |
$options = array();
|
| 621 |
if (!$fields) {
|
| 622 |
$options['attributes']['class'] = 'active';
|
| 623 |
}
|
| 624 |
$links[] = apachesolr_l($query->get_query_basic(), $path, $options);
|
| 625 |
foreach($fields as $field) {
|
| 626 |
if ($field['#name']) {
|
| 627 |
$new_query = clone $query;
|
| 628 |
$new_query->remove_filter($field['#name'], $field['#value']);
|
| 629 |
$options['query'] = $new_query->get_url_querystring();
|
| 630 |
$fielddisplay = theme("apachesolr_breadcrumb_". $field['#name'], $field['#value']);
|
| 631 |
if (!$fielddisplay) {
|
| 632 |
$fielddisplay = $field['#value'];
|
| 633 |
}
|
| 634 |
$links[] = theme('apachesolr_unclick_link', $fielddisplay, $new_query->get_path(), $options);
|
| 635 |
}
|
| 636 |
}
|
| 637 |
$content = theme('apachesolr_currentsearch', $response->response->numFound, $links);
|
| 638 |
return array('subject' => t('Current search'), 'content' => $content);
|
| 639 |
case 'is_book_bid':
|
| 640 |
return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by book'), 'apachesolr_search_get_book');
|
| 641 |
case 'language':
|
| 642 |
return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by language'), 'locale_language_name');
|
| 643 |
case 'uid':
|
| 644 |
return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by author'), 'apachesolr_search_get_username');
|
| 645 |
case 'type':
|
| 646 |
return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by type'), 'apachesolr_search_get_type');
|
| 647 |
case 'changed':
|
| 648 |
return apachesolr_date_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by modification date'));
|
| 649 |
case 'created':
|
| 650 |
return apachesolr_date_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by post date'));
|
| 651 |
|
| 652 |
default:
|
| 653 |
if ($fields = apachesolr_cck_fields()) {
|
| 654 |
foreach ($fields as $name => $field) {
|
| 655 |
if ($field['field_name'] == $delta) {
|
| 656 |
$index_key = apachesolr_index_key($field);
|
| 657 |
return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $index_key, t('Filter by @field', array('@field' => $field['label'])));
|
| 658 |
}
|
| 659 |
}
|
| 660 |
}
|
| 661 |
}
|
| 662 |
break;
|
| 663 |
}
|
| 664 |
break;
|
| 665 |
|
| 666 |
case 'configure':
|
| 667 |
if ($delta != 'currentsearch') {
|
| 668 |
return apachesolr_facetcount_form('apachesolr_search', $delta);
|
| 669 |
}
|
| 670 |
break;
|
| 671 |
|
| 672 |
case 'save':
|
| 673 |
if ($delta != 'currentsearch') {
|
| 674 |
apachesolr_facetcount_save($edit);
|
| 675 |
}
|
| 676 |
break;
|
| 677 |
}
|
| 678 |
}
|
| 679 |
|
| 680 |
/**
|
| 681 |
* Callback function for the 'Filter by book' facet block.
|
| 682 |
*/
|
| 683 |
function apachesolr_search_get_book($facet, &$options) {
|
| 684 |
if (is_numeric($facet)) {
|
| 685 |
return db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $facet));
|
| 686 |
}
|
| 687 |
else {
|
| 688 |
$options['html'] = TRUE;
|
| 689 |
return theme('placeholder', t('Not in any book'));
|
| 690 |
}
|
| 691 |
}
|
| 692 |
|
| 693 |
/**
|
| 694 |
* Callback function for the 'Filter by name' facet block.
|
| 695 |
*/
|
| 696 |
function apachesolr_search_get_username($facet) {
|
| 697 |
if (is_numeric($facet)) {
|
| 698 |
return theme('apachesolr_breadcrumb_uid', $facet);
|
| 699 |
}
|
| 700 |
return '';
|
| 701 |
}
|
| 702 |
|
| 703 |
/**
|
| 704 |
* Callback function for the 'Filter by type' facet block.
|
| 705 |
*/
|
| 706 |
function apachesolr_search_get_type($facet) {
|
| 707 |
$type = node_get_types('name', $facet);
|
| 708 |
// A disabled or missing node type returns FALSE.
|
| 709 |
return ($type === FALSE) ? $facet : $type;
|
| 710 |
}
|
| 711 |
|
| 712 |
/**
|
| 713 |
* Implementation of hook_form_[form_id]_alter().
|
| 714 |
*
|
| 715 |
* This adds the 0 option to the search admin form.
|
| 716 |
*/
|
| 717 |
function apachesolr_search_form_search_admin_settings_alter(&$form, $form_state) {
|
| 718 |
$form['indexing_throttle']['search_cron_limit']['#options']['0'] = '0';
|
| 719 |
ksort($form['indexing_throttle']['search_cron_limit']['#options']);
|
| 720 |
}
|
| 721 |
|
| 722 |
/**
|
| 723 |
* Implementation of hook_form_[form_id]_alter().
|
| 724 |
*/
|
| 725 |
function apachesolr_search_form_search_theme_form_alter(&$form, $form_state) {
|
| 726 |
apachesolr_search_form_search_block_form_alter($form, $form_state);
|
| 727 |
}
|
| 728 |
|
| 729 |
/**
|
| 730 |
* Implementation of hook_form_[form_id]_alter().
|
| 731 |
*/
|
| 732 |
function apachesolr_search_form_search_block_form_alter(&$form, $form_state) {
|
| 733 |
if (variable_get('apachesolr_search_make_default', 0)) {
|
| 734 |
if (!isset($form['#submit'])) {
|
| 735 |
$form['#submit'] = array('apachesolr_search_search_box_form_submit');
|
| 736 |
}
|
| 737 |
else {
|
| 738 |
$key = array_search('search_box_form_submit', $form['#submit']);
|
| 739 |
if ($key !== FALSE) {
|
| 740 |
// Replace the search module's function.
|
| 741 |
$form['#submit'][$key] = 'apachesolr_search_search_box_form_submit';
|
| 742 |
}
|
| 743 |
}
|
| 744 |
}
|
| 745 |
}
|
| 746 |
|
| 747 |
/**
|
| 748 |
* Process a block search form submission.
|
| 749 |
*/
|
| 750 |
function apachesolr_search_search_box_form_submit($form, &$form_state) {
|
| 751 |
$form_id = $form['form_id']['#value'];
|
| 752 |
$keys = $form_state['values'][$form_id];
|
| 753 |
// Handle Apache webserver clean URL quirks.
|
| 754 |
if (variable_get('clean_url', '0')) {
|
| 755 |
$keys = str_replace('+', '%2B', $keys);
|
| 756 |
}
|
| 757 |
$form_state['redirect'] = 'search/apachesolr_search/'. trim($keys);
|
| 758 |
}
|
| 759 |
|
| 760 |
/**
|
| 761 |
* Implementation of hook_form_[form_id]_alter().
|
| 762 |
*
|
| 763 |
* This adds spelling suggestions, retain filters to the search form.
|
| 764 |
*/
|
| 765 |
function apachesolr_search_form_search_form_alter(&$form, $form_state) {
|
| 766 |
|
| 767 |
if ($form['module']['#value'] == 'apachesolr_search') {
|
| 768 |
$filters = isset($_REQUEST['filters']) ? trim($_REQUEST['filters']) : '';
|
| 769 |
$form['basic']['apachesolr_search']['#tree'] = TRUE;
|
| 770 |
if ($filters) {
|
| 771 |
$form['basic']['apachesolr_search']['retain-filters'] = array(
|
| 772 |
'#type' => 'checkbox',
|
| 773 |
'#title' => t('Retain current filters'),
|
| 774 |
'#default_value' => !empty($_GET['retain-filters']),
|
| 775 |
);
|
| 776 |
}
|
| 777 |
$form['filters'] = array(
|
| 778 |
'#type' => 'hidden',
|
| 779 |
'#default_value' => $filters,
|
| 780 |
);
|
| 781 |
|
| 782 |
$form['#submit'] = array('apachesolr_search_form_search_submit');
|
| 783 |
if (variable_get('apachesolr_search_spellcheck', FALSE) && apachesolr_has_searched() && ($response = apachesolr_static_response_cache())) {
|
| 784 |
//Get spellchecker suggestions into an array.
|
| 785 |
$suggestions = get_object_vars($response->spellcheck->suggestions);
|
| 786 |
|
| 787 |
if ($suggestions) {
|
| 788 |
//Get the original query and replace words.
|
| 789 |
$query = apachesolr_current_query();
|
| 790 |
|
| 791 |
foreach($suggestions as $word => $value) {
|
| 792 |
$replacements[$word] = $value->suggestion[0];
|
| 793 |
}
|
| 794 |
$new_keywords = strtr($query->get_query_basic(), $replacements);
|
| 795 |
|
| 796 |
$form['basic']['suggestion'] = array(
|
| 797 |
'#prefix' => '<div class="spelling-suggestions">',
|
| 798 |
'#suffix' => '</div>',
|
| 799 |
'#type' => 'item',
|
| 800 |
'#title' => t('Did you mean'),
|
| 801 |
'#value' => l($new_keywords, $query->get_path($new_keywords)),
|
| 802 |
);
|
| 803 |
}
|
| 804 |
}
|
| 805 |
}
|
| 806 |
}
|
| 807 |
|
| 808 |
/**
|
| 809 |
* Added form submit function to account for Apache mode_rewrite quirks.
|
| 810 |
*
|
| 811 |
* @see apachesolr_search_form_search_form_alter()
|
| 812 |
*/
|
| 813 |
function apachesolr_search_form_search_submit($form, &$form_state) {
|
| 814 |
$fv = $form_state['values'];
|
| 815 |
$keys = $fv['processed_keys'];
|
| 816 |
$query = '';
|
| 817 |
$base = 'search/'. $fv['module'] . '/';
|
| 818 |
if (variable_get('clean_url', '0')) {
|
| 819 |
$keys = str_replace('+', '%2B', $keys);
|
| 820 |
}
|
| 821 |
if (!empty($fv['apachesolr_search']['retain-filters']) && $fv['filters']) {
|
| 822 |
$query = 'filters=' . rawurlencode($fv['filters']) . '&retain-filters=1';
|
| 823 |
}
|
| 824 |
$form_state['redirect'] = array($base . $keys, $query);
|
| 825 |
if ($keys == '' && $query == '') {
|
| 826 |
form_set_error('keys', t('Please enter some keywords.'));
|
| 827 |
}
|
| 828 |
}
|
| 829 |
|
| 830 |
/**
|
| 831 |
* Implementation of hook_form_[form_id]_alter().
|
| 832 |
*
|
| 833 |
* This adds options to the apachesolr admin form.
|
| 834 |
*/
|
| 835 |
function apachesolr_search_form_apachesolr_settings_alter(&$form, $form_state) {
|
| 836 |
$form['advanced']['apachesolr_search_make_default'] = array(
|
| 837 |
'#type' => 'radios',
|
| 838 |
'#title' => t('Make Apache Solr Search the default'),
|
| 839 |
'#default_value' => variable_get('apachesolr_search_make_default', 0),
|
| 840 |
'#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
|
| 841 |
'#description' => t('Hides core node search, and makes the search block submit to Apache Solr Search'),
|
| 842 |
);
|
| 843 |
$form['advanced']['apachesolr_search_default_previous'] = array(
|
| 844 |
'#type' => 'value',
|
| 845 |
'#value' => variable_get('apachesolr_search_make_default', 0),
|
| 846 |
);
|
| 847 |
$form['apachesolr_search_spellcheck'] = array(
|
| 848 |
'#type' => 'checkbox',
|
| 849 |
'#title' => t('Enable spellchecker and suggestions'),
|
| 850 |
'#default_value' => variable_get('apachesolr_search_spellcheck', FALSE),
|
| 851 |
'#description' => t('Enable spellchecker and get word suggestions. Also known as the "Did you mean ... ?" feature.'),
|
| 852 |
);
|
| 853 |
|
| 854 |
$form['#submit'][] = 'apachesolr_search_build_spellcheck';
|
| 855 |
$form['#submit'][] = 'apachesolr_search_make_default_submit';
|
| 856 |
// Move buttons to the bottom.
|
| 857 |
$buttons = $form['buttons'];
|
| 858 |
unset($form['buttons']);
|
| 859 |
$form['buttons'] = $buttons;
|
| 860 |
}
|
| 861 |
|
| 862 |
/**
|
| 863 |
* Form submit funtion - do a menu rebuild if needed.
|
| 864 |
*
|
| 865 |
* @see apachesolr_search_form_apachesolr_settings_alter()
|
| 866 |
*/
|
| 867 |
function apachesolr_search_make_default_submit($form, &$form_state) {
|
| 868 |
if ($form_state['values']['apachesolr_search_default_previous'] != variable_get('apachesolr_search_make_default', 0)) {
|
| 869 |
// Take account of path changes
|
| 870 |
menu_rebuild();
|
| 871 |
}
|
| 872 |
}
|
| 873 |
|
| 874 |
/**
|
| 875 |
* Implementation of hook_form_[form_id]_alter().
|
| 876 |
*
|
| 877 |
* Rebuild (empty) the spellcheck dictionary when the index is deleted..
|
| 878 |
*/
|
| 879 |
function apachesolr_search_form_apachesolr_delete_index_form_alter(&$form, $form_state) {
|
| 880 |
$form['submit']['#submit'][] = 'apachesolr_search_build_spellcheck';
|
| 881 |
}
|
| 882 |
|
| 883 |
function apachesolr_search_build_spellcheck() {
|
| 884 |
try {
|
| 885 |
$solr = apachesolr_get_solr();
|
| 886 |
$params['spellcheck'] = 'true';
|
| 887 |
$params['spellcheck.build'] = 'true';
|
| 888 |
$response = $solr->search('solr', 0, 0, $params);
|
| 889 |
}
|
| 890 |
catch (Exception $e) {
|
| 891 |
watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR);
|
| 892 |
}
|
| 893 |
}
|
| 894 |
|
| 895 |
/**
|
| 896 |
* Implementation of hook_theme().
|
| 897 |
*/
|
| 898 |
function apachesolr_search_theme() {
|
| 899 |
return array(
|
| 900 |
'apachesolr_breadcrumb_is_book_bid' => array(
|
| 901 |
'arguments' => array('bid' => NULL),
|
| 902 |
),
|
| 903 |
'apachesolr_breadcrumb_uid' => array(
|
| 904 |
'arguments' => array('uid' => NULL),
|
| 905 |
),
|
| 906 |
'apachesolr_breadcrumb_tid' => array(
|
| 907 |
'arguments' => array('tid' => NULL),
|
| 908 |
),
|
| 909 |
'apachesolr_breadcrumb_type' => array(
|
| 910 |
'arguments' => array('type' => NULL),
|
| 911 |
),
|
| 912 |
'apachesolr_breadcrumb_changed' => array(
|
| 913 |
'arguments' => array('type' => NULL),
|
| 914 |
),
|
| 915 |
'apachesolr_breadcrumb_created' => array(
|
| 916 |
'arguments' => array('type' => NULL),
|
| 917 |
),
|
| 918 |
'apachesolr_currentsearch' => array(
|
| 919 |
'arguments' => array('total_found' => NULL, 'links' => NULL),
|
| 920 |
),
|
| 921 |
'apachesolr_search_snippets' => array(
|
| 922 |
'arguments' => array('doc' => NULL, 'snippets' => NULL),
|
| 923 |
),
|
| 924 |
);
|
| 925 |
}
|
| 926 |
|
| 927 |
function theme_apachesolr_breadcrumb_date_range($range) {
|
| 928 |
if (preg_match('@[\[\{](\S+) TO (\S+)[\]\}]@', $range, $match)) {
|
| 929 |
return apachesolr_date_format_range($match[1], $match[2]);
|
| 930 |
}
|
| 931 |
return $range;
|
| 932 |
}
|
| 933 |
|
| 934 |
function theme_apachesolr_breadcrumb_changed($range) {
|
| 935 |
return theme_apachesolr_breadcrumb_date_range($range);
|
| 936 |
}
|
| 937 |
|
| 938 |
function theme_apachesolr_breadcrumb_created($range) {
|
| 939 |
return theme_apachesolr_breadcrumb_date_range($range);
|
| 940 |
}
|
| 941 |
|
| 942 |
/**
|
| 943 |
* Return the username from $uid
|
| 944 |
*/
|
| 945 |
function theme_apachesolr_breadcrumb_uid($uid) {
|
| 946 |
if ($uid == 0) {
|
| 947 |
return variable_get('anonymous', t('Anonymous'));
|
| 948 |
}
|
| 949 |
else {
|
| 950 |
return db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $uid));
|
| 951 |
}
|
| 952 |
}
|
| 953 |
|
| 954 |
/**
|
| 955 |
* Return the term name from $tid.
|
| 956 |
*/
|
| 957 |
function theme_apachesolr_breadcrumb_tid($tid) {
|
| 958 |
$term = taxonomy_get_term($tid);
|
| 959 |
return $term->name;
|
| 960 |
}
|
| 961 |
|
| 962 |
/**
|
| 963 |
* Return the human readable text for a content type.
|
| 964 |
*/
|
| 965 |
function theme_apachesolr_breadcrumb_type($type) {
|
| 966 |
return node_get_types('name', $type);
|
| 967 |
}
|
| 968 |
|
| 969 |
/**
|
| 970 |
* Return the title of a book.
|
| 971 |
*/
|
| 972 |
function theme_apachesolr_breadcrumb_is_book_bid($bid) {
|
| 973 |
if (is_numeric($bid)) {
|
| 974 |
return db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $bid));
|
| 975 |
}
|
| 976 |
else {
|
| 977 |
return t('Not in any book');
|
| 978 |
}
|
| 979 |
}
|
| 980 |
|
| 981 |
/**
|
| 982 |
* Return current search block contents
|
| 983 |
*/
|
| 984 |
function theme_apachesolr_currentsearch($total_found, $links) {
|
| 985 |
return theme_item_list($links, format_plural($total_found, 'Search found 1 item', 'Search found @count items'));
|
| 986 |
}
|
| 987 |
|
| 988 |
/**
|
| 989 |
* Theme the highlighted snippet text for a search entry.
|
| 990 |
*
|
| 991 |
* @param object $doc
|
| 992 |
* @param array $snippets
|
| 993 |
*
|
| 994 |
*/
|
| 995 |
function theme_apachesolr_search_snippets($doc, $snippets) {
|
| 996 |
return implode(' ... ', $snippets) .' ...';
|
| 997 |
}
|
| 998 |
|