View source
<?php
define('APACHESOLR_READ_WRITE', 0);
define('APACHESOLR_READ_ONLY', 1);
define('APACHESOLR_API_VERSION', '3.0');
function apachesolr_menu() {
$items = array();
$items['admin/config/search/apachesolr'] = array(
'title' => 'Apache Solr search',
'description' => 'Administer Apache Solr.',
'page callback' => 'apachesolr_status_page',
'access arguments' => array(
'administer search',
),
'weight' => -8,
'file' => 'apachesolr.admin.inc',
);
$items['admin/config/search/apachesolr/index'] = array(
'title' => 'Default index',
'description' => 'Administer Apache Solr.',
'page callback' => 'apachesolr_status_page',
'access arguments' => array(
'administer search',
),
'weight' => -8,
'file' => 'apachesolr.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/search/apachesolr/settings'] = array(
'title' => 'Settings',
'weight' => 10,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_settings',
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$settings_path = 'admin/config/search/apachesolr/settings/';
$items[$settings_path . '%apachesolr_environment/index'] = array(
'title' => 'Index',
'page callback' => 'apachesolr_status_page',
'page arguments' => array(
5,
),
'access arguments' => array(
'administer search',
),
'weight' => 0,
'file' => 'apachesolr.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$items[$settings_path . '%apachesolr_environment/index/remaining'] = array(
'title' => 'Remaining',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_index_action_form_remaining_confirm',
5,
),
'file' => 'apachesolr.admin.inc',
'access arguments' => array(
'administer search',
),
'type' => MENU_CALLBACK,
);
$items[$settings_path . '%apachesolr_environment/index/delete'] = array(
'title' => 'Reindex',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_index_action_form_delete_confirm',
5,
),
'file' => 'apachesolr.admin.inc',
'access arguments' => array(
'administer search',
),
'type' => MENU_CALLBACK,
);
$items[$settings_path . '%apachesolr_environment/index/reset'] = array(
'title' => 'Reindex',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_index_action_form_reset_confirm',
5,
),
'file' => 'apachesolr.admin.inc',
'access arguments' => array(
'administer search',
),
'type' => MENU_CALLBACK,
);
$items[$settings_path . '%apachesolr_environment/index/reset/confirm'] = array(
'title' => 'Confirm the re-indexing of all content',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_clear_index_confirm',
5,
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_CALLBACK,
);
$items[$settings_path . '%apachesolr_environment/index/delete/confirm'] = array(
'title' => 'Confirm index deletion',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_delete_index_confirm',
5,
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_CALLBACK,
);
$items[$settings_path . '%apachesolr_environment/edit'] = array(
'title' => 'Edit',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_environment_edit_form',
5,
),
'description' => 'Edit Apache Solr search environment.',
'access arguments' => array(
'administer search',
),
'weight' => 10,
'file' => 'apachesolr.admin.inc',
'type' => MENU_LOCAL_TASK,
);
$items[$settings_path . '%apachesolr_environment/clone'] = array(
'title' => 'Apache Solr search environment clone',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_environment_clone_form',
5,
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
);
$items[$settings_path . '%apachesolr_environment/delete'] = array(
'title' => 'Apache Solr search environment delete',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_environment_delete_form',
5,
),
'access callback' => 'apachesolr_environment_delete_page_access',
'access arguments' => array(
'administer search',
5,
),
'file' => 'apachesolr.admin.inc',
);
$items[$settings_path . 'add'] = array(
'title' => 'Add search environment',
'description' => 'Add Apache Solr environment.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_environment_edit_form',
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_LOCAL_ACTION,
);
$items['admin/config/search/apachesolr/index/confirm/clear'] = array(
'title' => 'Confirm the re-indexing of all content',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_clear_index_confirm',
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_CALLBACK,
);
$items['admin/config/search/apachesolr/index/confirm/delete'] = array(
'title' => 'Confirm index deletion',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_delete_index_confirm',
),
'access arguments' => array(
'administer search',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_CALLBACK,
);
$reports_path = 'admin/reports/apachesolr';
$items[$reports_path] = array(
'title' => 'Apache Solr search index',
'description' => 'Information about the contents of the index on the server',
'page callback' => 'apachesolr_index_report',
'access arguments' => array(
'access site reports',
),
'file' => 'apachesolr.admin.inc',
);
$items[$reports_path . '/%apachesolr_environment'] = array(
'title' => 'Apache Solr search index',
'description' => 'Information about the contents of the index on the server',
'page callback' => 'apachesolr_index_report',
'page arguments' => array(
3,
),
'access arguments' => array(
'access site reports',
),
'file' => 'apachesolr.admin.inc',
);
$items[$reports_path . '/%apachesolr_environment/index'] = array(
'title' => 'Search index',
'file' => 'apachesolr.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items[$reports_path . '/%apachesolr_environment/conf'] = array(
'title' => 'Configuration files',
'page callback' => 'apachesolr_config_files_overview',
'access arguments' => array(
'access site reports',
),
'file' => 'apachesolr.admin.inc',
'weight' => 5,
'type' => MENU_LOCAL_TASK,
);
$items[$reports_path . '/%apachesolr_environment/conf/%'] = array(
'title' => 'Configuration file',
'page callback' => 'apachesolr_config_file',
'page arguments' => array(
5,
3,
),
'access arguments' => array(
'access site reports',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_CALLBACK,
);
if (module_exists('devel')) {
$items['node/%node/devel/apachesolr'] = array(
'title' => 'Apache Solr',
'page callback' => 'apachesolr_devel',
'page arguments' => array(
1,
),
'access arguments' => array(
'access devel information',
),
'file' => 'apachesolr.admin.inc',
'type' => MENU_LOCAL_TASK,
);
}
if (module_exists('facetapi')) {
$file_path = drupal_get_path('module', 'facetapi');
$first = TRUE;
foreach (facetapi_get_realm_info() as $realm_name => $realm) {
if ($first) {
$first = FALSE;
$items[$settings_path . '%apachesolr_environment/facets'] = array(
'title' => 'Facets',
'page callback' => 'apachesolr_enabled_facets_page',
'page arguments' => array(
$realm_name,
5,
),
'weight' => -5,
'access arguments' => array(
'administer search',
),
'file path' => $file_path,
'file' => 'facetapi.admin.inc',
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
);
}
else {
$items[$settings_path . '%apachesolr_environment/facets/' . $realm_name] = array(
'title' => $realm['label'],
'page callback' => 'apachesolr_enabled_facets_page',
'page arguments' => array(
$realm_name,
5,
),
'weight' => -5,
'access arguments' => array(
'administer search',
),
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file path' => $file_path,
'file' => 'facetapi.admin.inc',
);
}
}
}
return $items;
}
function apachesolr_enabled_facets_page($realm_name, $environment = NULL) {
$page = array();
if (isset($environment['env_id'])) {
$env_id = $environment['env_id'];
}
else {
$env_id = apachesolr_default_environment();
}
$searcher = 'apachesolr@' . $env_id;
$page['apachesolr_environment'] = array(
'#theme' => 'apachesolr_settings_title',
'#env_id' => $env_id,
);
$page['settings'] = drupal_get_form('facetapi_realm_settings_form', $searcher, $realm_name);
return $page;
}
function apachesolr_facetapi_searcher_info() {
$info = array();
foreach (apachesolr_load_all_environments() as $id => $environment) {
$info['apachesolr@' . $id] = array(
'label' => t('Apache Solr environment: @environment', array(
'@environment' => $environment['name'],
)),
'adapter' => 'apachesolr',
'instance' => $id,
'path' => '',
'supports facet mincount' => TRUE,
'supports facet missing' => TRUE,
'include default facets' => FALSE,
);
}
return $info;
}
function apachesolr_facetapi_adapters() {
return array(
'apachesolr' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiAdapter',
),
),
);
}
function apachesolr_facetapi_query_types() {
return array(
'apachesolr_term' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiTerm',
'adapter' => 'apachesolr',
),
),
'apachesolr_date' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiDate',
'adapter' => 'apachesolr',
),
),
'apachesolr_numeric_range' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiNumericRange',
'adapter' => 'apachesolr',
),
),
'apachesolr_geo' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiGeo',
'adapter' => 'apachesolr',
),
),
);
}
function apachesolr_facetapi_facet_info($searcher_info) {
$facets = array();
if ('apachesolr' == $searcher_info['module']) {
$environment = apachesolr_environment_load($searcher_info['instance']);
if (!empty($environment['conf']['facet callbacks'])) {
foreach ($environment['conf']['facet callbacks'] as $callback) {
if (is_callable($callback)) {
$facets = array_merge($facets, call_user_func($callback, $searcher_info));
}
}
}
elseif (isset($searcher_info['types']['node'])) {
$facets = apachesolr_default_node_facet_info();
}
}
return $facets;
}
function apachesolr_default_node_facet_info() {
return array_merge(apachesolr_common_node_facets(), apachesolr_entity_field_facets('node'));
}
function apachesolr_entity_field_facets($entity_type) {
$facets = array();
foreach (apachesolr_entity_fields($entity_type) as $field_nm => $entity_fields) {
foreach ($entity_fields as $field_info) {
if (!empty($field_info['facets'])) {
$field = apachesolr_index_key($field_info);
$facets[$field] = array(
'label' => check_plain($field_info['display_name']),
'dependency plugins' => $field_info['dependency plugins'],
'field api name' => $field_info['field']['field_name'],
'description' => t('Filter by field @field of type @type.', array(
'@type' => $field_info['field']['type'],
'@field' => $field_info['field']['field_name'],
)),
'map callback' => $field_info['map callback'],
'map options' => $field_info,
'hierarchy callback' => $field_info['hierarchy callback'],
);
if (!empty($field_info['facet mincount allowed'])) {
$facets[$field]['facet mincount allowed'] = $field_info['facet mincount allowed'];
}
if (!empty($field_info['facet missing allowed'])) {
$facets[$field]['facet missing allowed'] = $field_info['facet missing allowed'];
}
if (!empty($field_info['query types'])) {
$facets[$field]['query types'] = $field_info['query types'];
}
if (!empty($field_info['allowed operators'])) {
$facets[$field]['allowed operators'] = $field_info['allowed operators'];
}
if (!empty($field_info['query type'])) {
$facets[$field]['query type'] = $field_info['query type'];
}
if (!empty($field_info['min callback'])) {
$facets[$field]['min callback'] = $field_info['min callback'];
}
if (!empty($field_info['max callback'])) {
$facets[$field]['max callback'] = $field_info['max callback'];
}
if (!empty($field_info['map callback'])) {
$facets[$field]['map callback'] = $field_info['map callback'];
}
if (!empty($field_info['alter callbacks'])) {
$facets[$field]['alter callbacks'] = $field_info['alter callbacks'];
}
}
}
}
return $facets;
}
function apachesolr_common_node_facets() {
$facets['bundle'] = array(
'label' => t('Content type'),
'description' => t('Filter by content type.'),
'field api bundles' => array(
'node',
),
'map callback' => 'facetapi_map_bundle',
'values callback' => 'facetapi_callback_type_values',
'facet mincount allowed' => TRUE,
'dependency plugins' => array(
'role',
),
);
$facets['author'] = array(
'label' => t('Author'),
'description' => t('Filter by author.'),
'field' => 'is_uid',
'map callback' => 'facetapi_map_author',
'values callback' => 'facetapi_callback_user_values',
'facet mincount allowed' => TRUE,
'dependency plugins' => array(
'bundle',
'role',
),
);
$facets['language'] = array(
'label' => t('Language'),
'description' => t('Filter by language.'),
'field' => 'ss_language',
'map callback' => 'facetapi_map_language',
'values callback' => 'facetapi_callback_language_values',
'facet mincount allowed' => TRUE,
'dependency plugins' => array(
'bundle',
'role',
),
);
$facets['created'] = array(
'label' => t('Post date'),
'description' => t('Filter by the date the node was posted.'),
'field' => 'ds_created',
'query types' => array(
'date',
),
'allowed operators' => array(
FACETAPI_OPERATOR_AND => TRUE,
),
'map callback' => 'facetapi_map_date',
'min callback' => 'facetapi_get_min_date',
'max callback' => 'facetapi_get_max_date',
'dependency plugins' => array(
'bundle',
'role',
),
'default sorts' => array(
array(
'active',
SORT_DESC,
),
array(
'indexed',
SORT_ASC,
),
),
);
$facets['changed'] = array(
'label' => t('Updated date'),
'description' => t('Filter by the date the node was last modified.'),
'field' => 'ds_changed',
'query types' => array(
'date',
),
'allowed operators' => array(
FACETAPI_OPERATOR_AND => TRUE,
),
'map callback' => 'facetapi_map_date',
'min callback' => 'facetapi_get_min_date',
'max callback' => 'facetapi_get_max_date',
'dependency plugins' => array(
'bundle',
'role',
),
'default sorts' => array(
array(
'active',
SORT_DESC,
),
array(
'indexed',
SORT_ASC,
),
),
);
if (module_exists('book')) {
$facets['book'] = array(
'label' => t('Book'),
'description' => t('Filter by the book that the node belongs to.'),
'field' => 'is_book_bid',
'map callback' => 'apachesolr_map_book',
'facet mincount allowed' => TRUE,
'dependency plugins' => array(
'bundle',
'role',
),
);
}
return $facets;
}
function apachesolr_map_book(array $values) {
$map = array();
if (!empty($values)) {
foreach (book_get_books() as $bid => $book) {
if (in_array($bid, $values)) {
$map[$bid] = $book['title'];
}
}
}
return $map;
}
function apachesolr_form_book_outline_form_alter(&$form, $form_state) {
$form['#submit'][] = 'apachesolr_mark_book_outline_node';
}
function apachesolr_mark_book_outline_node($form, $form_state) {
apachesolr_mark_entity('node', $form['#node']->nid);
}
function apachesolr_failure($search_name, $querystring) {
$fail_rule = variable_get('apachesolr_failure', 'apachesolr:show_error');
switch ($fail_rule) {
case 'apachesolr:show_error':
drupal_set_message(t('Search is temporarily unavailable. If the problem persists, please contact the site administrator.'), 'error');
break;
case 'apachesolr:show_no_results':
break;
default:
if (module_exists('search')) {
$search_info = search_get_info();
if (isset($search_info[$fail_rule])) {
$search_info = $search_info[$fail_rule];
drupal_set_message(t("%search_name is not available. Your search is being redirected.", array(
'%search_name' => $search_name,
)));
drupal_goto('search/' . $search_info['path'] . '/' . rawurlencode($querystring));
}
}
break;
}
}
function apachesolr_site_hash() {
if (!($hash = variable_get('apachesolr_site_hash', FALSE))) {
global $base_url;
$hash = substr(base_convert(sha1(uniqid($base_url, TRUE)), 16, 36), 0, 6);
variable_set('apachesolr_site_hash', $hash);
}
return $hash;
}
function apachesolr_document_id($id, $entity_type = 'node') {
return apachesolr_site_hash() . "/{$entity_type}/" . $id;
}
function apachesolr_mark_entity($entity_type, $entity_id) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$table = apachesolr_get_indexer_table($entity_type);
if (!empty($table)) {
db_update($table)
->condition('entity_id', $entity_id)
->fields(array(
'changed' => REQUEST_TIME,
))
->execute();
}
}
function apachesolr_user_update(&$edit, $account, $category) {
if (isset($account->name) && isset($account->original) && isset($account->original->name) && $account->name != $account->original->name) {
$table = apachesolr_get_indexer_table('node');
switch (db_driver()) {
case 'mysql':
$table = db_escape_table($table);
$query = "UPDATE {{$table}} asn\n INNER JOIN {node} n ON asn.entity_id = n.nid SET asn.changed = :changed\n WHERE n.uid = :uid";
$result = db_query($query, array(
':changed' => REQUEST_TIME,
':uid' => $account->uid,
));
break;
default:
$nids = db_select('node')
->fields('node', array(
'nid',
))
->where("uid = :uid", array(
':uid' => $account->uid,
));
$update = db_update($table)
->condition('entity_id', $nids, 'IN')
->fields(array(
'changed' => REQUEST_TIME,
))
->execute();
}
}
}
function apachesolr_taxonomy_term_update($term) {
$table = apachesolr_get_indexer_table('node');
switch (db_driver()) {
case 'mysql':
$table = db_escape_table($table);
$query = "UPDATE {{$table}} asn\n INNER JOIN {taxonomy_index} ti ON asn.entity_id = ti.nid SET asn.changed = :changed\n WHERE ti.tid = :tid";
$result = db_query($query, array(
':changed' => REQUEST_TIME,
':tid' => $term->tid,
));
break;
default:
$nids = db_select('taxonomy_index')
->fields('taxonomy_index', array(
'nid',
))
->where("tid = :tid", array(
':tid' => $term->tid,
));
$update = db_update($table)
->condition('entity_id', $nids, 'IN')
->fields(array(
'changed' => REQUEST_TIME,
))
->execute();
}
}
function apachesolr_comment_insert($comment) {
apachesolr_mark_entity('node', $comment->nid);
}
function apachesolr_comment_update($comment) {
apachesolr_mark_entity('node', $comment->nid);
}
function apachesolr_comment_delete($comment) {
apachesolr_mark_entity('node', $comment->nid);
}
function apachesolr_comment_publish($comment) {
apachesolr_mark_entity('node', $comment->nid);
}
function apachesolr_comment_unpublish($comment) {
apachesolr_mark_entity('node', $comment->nid);
}
function apachesolr_node_type_delete($info) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$env_id = apachesolr_default_environment();
$existing_bundles = apachesolr_get_index_bundles($env_id, 'node');
$new_bundles = $existing_bundles;
$index = array_search($info->type, $existing_bundles);
if ($index !== FALSE) {
unset($new_bundles[$index]);
$new_bundles = array_values($new_bundles);
apachesolr_index_set_bundles($env_id, 'node', $new_bundles);
}
apachesolr_index_delete_bundles($env_id, 'node', array(
$info->type,
));
$bundles_changed_callback = apachesolr_entity_get_callback('node', 'bundles changed callback');
if (!empty($bundles_changed_callback)) {
call_user_func($bundles_changed_callback, $env_id, $existing_bundles, $new_bundles);
}
apachesolr_environments_clear_cache();
}
function apachesolr_node_type_update($info) {
if (!empty($info->old_type) && $info->old_type != $info->type) {
$table = apachesolr_get_indexer_table('node');
switch (db_driver()) {
case 'mysql':
$table = db_escape_table($table);
$query = "UPDATE {{$table}} asn\n INNER JOIN {node} n ON asn.entity_id = n.nid SET asn.changed = :changed\n WHERE (n.type = :type OR n.type = :old_type)";
$result = db_query($query, array(
':changed' => REQUEST_TIME,
':type' => $info->type,
':old_type' => $info->old_type,
));
break;
default:
$nids = db_select('node')
->fields('node', array(
'nid',
))
->where("type = :new OR type = :old", array(
':new' => $info->type,
':old' => $info->old_type,
));
$update = db_update($table)
->condition('entity_id', $nids, 'IN')
->fields(array(
'changed' => REQUEST_TIME,
))
->execute();
}
db_update('apachesolr_index_bundles')
->condition('bundle', $info->old_type)
->condition('entity_type', 'node')
->fields(array(
'bundle' => $info->type,
))
->execute();
apachesolr_environments_clear_cache();
}
}
function apachesolr_node_type_insert($info) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$envs = apachesolr_load_all_environments();
$bundles = array();
foreach ($envs as $env) {
if (isset($env['index_bundles']['node'])) {
$bundles = $env['index_bundles']['node'];
}
if (!in_array($info->type, $bundles)) {
$bundles[] = $info->type;
apachesolr_index_set_bundles($env['env_id'], 'node', $bundles);
apachesolr_environments_clear_cache();
}
}
}
function apachesolr_date_iso($date_timestamp) {
return gmdate('Y-m-d\\TH:i:s\\Z', $date_timestamp);
}
function apachesolr_flatten_documents_array($documents, &$tmp) {
foreach ($documents as $index => $item) {
if (is_array($item)) {
apachesolr_flatten_documents_array($item, $tmp);
}
elseif (is_object($item)) {
$tmp[] = $item;
}
}
}
function apachesolr_flush_caches() {
return array(
'cache_apachesolr',
);
}
function apachesolr_clear_cache($env_id) {
if (is_array($env_id)) {
$env_id = NULL;
}
try {
$solr = apachesolr_get_solr($env_id);
$solr
->clearCache();
} catch (Exception $e) {
apachesolr_log_exception($env_id, $e);
drupal_set_message(nl2br(check_plain($e
->getMessage())), 'warning');
}
}
function apachesolr_set_stats_message($text, $type = 'status', $repeat = FALSE) {
$env_id = apachesolr_default_environment();
try {
$solr = apachesolr_get_solr($env_id);
$stats_summary = $solr
->getStatsSummary();
drupal_set_message(check_plain(t($text, $stats_summary)), $type, FALSE);
} catch (Exception $e) {
apachesolr_log_exception($env_id, $e);
}
}
function apachesolr_get_last_index_position($env_id, $entity_type) {
$stored = apachesolr_environment_variable_get($env_id, 'apachesolr_index_last', array());
return isset($stored[$entity_type]) ? $stored[$entity_type] : array(
'last_changed' => 0,
'last_entity_id' => 0,
);
}
function apachesolr_set_last_index_position($env_id, $entity_type, $last_changed, $last_entity_id) {
$stored = apachesolr_environment_variable_get($env_id, 'apachesolr_index_last', array());
$stored[$entity_type] = array(
'last_changed' => $last_changed,
'last_entity_id' => $last_entity_id,
);
apachesolr_environment_variable_set($env_id, 'apachesolr_index_last', $stored);
}
function apachesolr_clear_last_index_position($env_id = NULL, $entity_type = NULL) {
if (!empty($env_id)) {
$stored = apachesolr_environment_variable_get($env_id, 'apachesolr_index_last', array());
if ($entity_type) {
unset($stored[$entity_type]);
}
else {
$stored = array();
}
apachesolr_environment_variable_set($env_id, 'apachesolr_index_last', $stored);
}
else {
$environments = apachesolr_load_all_environments();
foreach (array_keys($environments) as $env_id) {
apachesolr_environment_variable_set($env_id, 'apachesolr_index_last', array());
}
}
}
function apachesolr_set_last_index_updated($env_id, $timestamp = 0) {
apachesolr_environment_variable_set($env_id, 'apachesolr_index_updated', $timestamp);
}
function apachesolr_get_last_index_updated($env_id) {
return apachesolr_environment_variable_get($env_id, 'apachesolr_index_updated', 0);
}
function apachesolr_cron($env_id = NULL) {
$environments = array();
if (empty($env_id)) {
$environments = array_keys(apachesolr_load_all_environments());
}
else {
$environments[] = $env_id;
}
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$optimize_interval = variable_get('apachesolr_optimize_interval', 60 * 60 * 24);
$optimize_attempt_interval = variable_get('apachesolr_optimize_attempt_interval', 60 * 60);
foreach ($environments as $env_id) {
if (apachesolr_environment_variable_get($env_id, 'apachesolr_read_only', APACHESOLR_READ_WRITE) == APACHESOLR_READ_ONLY) {
continue;
}
foreach (entity_get_info() as $type => $info) {
$bundles = apachesolr_get_index_bundles($env_id, $type);
if (empty($bundles)) {
continue;
}
if (isset($info['apachesolr']['cron_check'])) {
$callback = $info['apachesolr']['cron_check'];
call_user_func($callback);
}
}
$time = time();
$last_optimize_success = apachesolr_environment_variable_get($env_id, 'apachesolr_last_optimize_success', 0);
$last_optimize_attempt = apachesolr_environment_variable_get($env_id, 'apachesolr_last_optimize_attempt', 0);
if ($optimize_interval && $optimize_attempt_interval && $time - $last_optimize_success >= $optimize_interval && $time - $last_optimize_attempt >= $optimize_attempt_interval) {
try {
$solr = apachesolr_get_solr($env_id);
apachesolr_environment_variable_set($env_id, 'apachesolr_last_optimize_attempt', $time);
$solr
->optimize(FALSE, FALSE, 600);
apachesolr_environment_variable_set($env_id, 'apachesolr_last_optimize_success', $time);
apachesolr_set_last_index_updated($env_id, $time);
} catch (Exception $e) {
apachesolr_log_exception($env_id, $e);
}
}
$updated = apachesolr_get_last_index_updated($env_id);
if ($updated > 0) {
try {
$solr = apachesolr_get_solr($env_id);
$solr
->clearCache();
$solr
->getLuke();
if ($time - $updated >= variable_get('apachesolr_cache_delay', 300)) {
apachesolr_set_last_index_updated($env_id);
}
} catch (Exception $e) {
apachesolr_log_exception($env_id, $e);
}
}
$limit = variable_get('apachesolr_cron_limit', 50);
apachesolr_index_entities($env_id, $limit);
}
}
function apachesolr_form_node_type_form_alter(&$form, $form_state) {
$form['#submit'][] = 'apachesolr_clear_cache';
}
function apachesolr_form_field_ui_field_overview_form_alter(&$form, $form_state) {
$form['#submit'][] = 'apachesolr_clear_cache';
}
function apachesolr_form_field_ui_field_edit_form_alter(&$form, $form_state) {
$form['#submit'][] = 'apachesolr_clear_cache';
}
function apachesolr_set_facetapi_breadcrumb(FacetapiAdapter $adapter, array $realm) {
if ('apachesolr' == $adapter
->getId()) {
list(, $env_id) = explode('@', $adapter
->getSearcher());
$breadcrumb = drupal_get_breadcrumb();
$breadcrumb[] = l(t('Apache Solr search environment edit'), 'admin/config/search/apachesolr/settings/' . $env_id);
$breadcrumb[] = l($realm['label'], 'admin/config/search/apachesolr/settings/' . $env_id . '/facets/' . $realm['name']);
drupal_set_breadcrumb($breadcrumb);
}
}
function apachesolr_form_facetapi_facet_settings_form_alter(&$form, $form_state) {
apachesolr_set_facetapi_breadcrumb($form['#facetapi']['adapter'], $form['#facetapi']['realm']);
}
function apachesolr_form_facetapi_facet_dependencies_form_alter(&$form, $form_state) {
apachesolr_set_facetapi_breadcrumb($form['#facetapi']['adapter'], $form['#facetapi']['realm']);
}
function apachesolr_has_searched($env_id, $searched = NULL) {
$_searched =& drupal_static(__FUNCTION__, FALSE);
if (is_bool($searched)) {
$_searched[$env_id] = $searched;
}
if (!isset($_searched[$env_id])) {
return FALSE;
}
return $_searched[$env_id];
}
function apachesolr_suppress_blocks($env_id, $suppress = NULL) {
$_suppress =& drupal_static(__FUNCTION__, FALSE);
if (is_bool($suppress)) {
$_suppress[$env_id] = $suppress;
}
if (!isset($_suppress[$env_id])) {
return FALSE;
}
return $_suppress[$env_id];
}
function apachesolr_default_environment($env_id = NULL) {
$default_env_id =& drupal_static(__FUNCTION__, NULL);
if (isset($env_id)) {
$default_env_id = $env_id;
}
if (empty($default_env_id)) {
$default_env_id = variable_get('apachesolr_default_environment', 'solr');
}
return $default_env_id;
}
function apachesolr_set_default_environment($env_id) {
$old_env_id = variable_get('apachesolr_default_environment', 'solr');
variable_set('apachesolr_default_environment', $env_id);
module_invoke_all('apachesolr_default_environment', $env_id, $old_env_id);
}
function apachesolr_get_solr($env_id = NULL) {
$solr_cache =& drupal_static(__FUNCTION__);
$environments = apachesolr_load_all_environments();
if (!interface_exists('DrupalApacheSolrServiceInterface')) {
require_once dirname(__FILE__) . '/apachesolr.interface.inc';
}
if (empty($env_id)) {
$env_id = apachesolr_default_environment();
}
elseif (empty($environments[$env_id])) {
throw new Exception(t('Invalid Apache Solr environment: @env_id.', array(
'@env_id' => $env_id,
)));
}
if (isset($environments[$env_id])) {
$class = $environments[$env_id]['service_class'];
if (empty($solr_cache[$env_id])) {
if (empty($class)) {
$class = variable_get('apachesolr_service_class', 'DrupalApacheSolrService');
}
$solr = new $class($environments[$env_id]['url'], $env_id);
$soft_commit = apachesolr_environment_variable_get($env_id, 'apachesolr_soft_commit', FALSE);
if ($soft_commit) {
$solr
->setSoftCommit($soft_commit);
}
$solr_cache[$env_id] = $solr;
}
return $solr_cache[$env_id];
}
else {
throw new Exception('No default Apache Solr environment.');
}
}
function apachesolr_load_all_environments() {
$environments =& drupal_static(__FUNCTION__);
if (isset($environments)) {
return $environments;
}
$cache = cache_get('apachesolr:environments', 'cache_apachesolr');
if (isset($cache->data)) {
$environments = $cache->data;
}
elseif (!db_table_exists('apachesolr_index_bundles') || !db_table_exists('apachesolr_environment')) {
$environments = array();
}
else {
if (module_exists('ctools')) {
ctools_include('export');
$environments = ctools_export_load_object('apachesolr_environment', 'all');
foreach ($environments as &$environment) {
$environment = (array) $environment;
}
}
else {
$environments = db_query('SELECT * FROM {apachesolr_environment}')
->fetchAllAssoc('env_id', PDO::FETCH_ASSOC);
}
apachesolr_environment_load_subrecords($environments);
cache_set('apachesolr:environments', $environments, 'cache_apachesolr');
}
$conf_environments = variable_get('apachesolr_environments', array());
if (!empty($conf_environments)) {
$environments = drupal_array_merge_deep($environments, $conf_environments);
}
return $environments;
}
function apachesolr_environment_load($env_id) {
$environments = apachesolr_load_all_environments();
return isset($environments[$env_id]) ? $environments[$env_id] : FALSE;
}
function apachesolr_environment_delete_page_access($permission, $environment) {
$is_default = $environment['env_id'] == apachesolr_default_environment();
return !$is_default && user_access($permission);
}
function apachesolr_environment_delete($env_id) {
$environment = apachesolr_environment_load($env_id);
if ($environment) {
db_delete('apachesolr_environment')
->condition('env_id', $env_id)
->execute();
db_delete('apachesolr_environment_variable')
->condition('env_id', $env_id)
->execute();
db_delete('apachesolr_index_bundles')
->condition('env_id', $env_id)
->execute();
module_invoke_all('apachesolr_environment_delete', $environment);
apachesolr_environments_clear_cache();
}
}
function apachesolr_environment_clone($env_id) {
$environment = apachesolr_environment_load($env_id);
$environments = apachesolr_load_all_environments();
$environment['env_id'] = apachesolr_create_unique_id($environments, $env_id);
$environment['name'] = $environment['name'] . ' [cloned]';
apachesolr_environment_save($environment);
}
function apachesolr_create_unique_id($existing, $id) {
$count = 0;
$cloned_env_int = 0;
do {
$new_id = $id . '_' . $count;
$count++;
} while (isset($existing[$new_id]));
return $new_id;
}
function apachesolr_environment_save($environment) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$default = array(
'env_id' => '',
'name' => '',
'url' => '',
'service_class' => '',
);
$old_environment = apachesolr_environment_load($environment['env_id']);
if (!empty($old_environment['in_code_only']) && $environment != $old_environment) {
$environment = drupal_array_merge_deep($old_environment, $environment);
}
$conf = isset($environment['conf']) ? $environment['conf'] : array();
$index_bundles = isset($environment['index_bundles']) ? $environment['index_bundles'] : array();
$environment = array_intersect_key($environment, $default);
db_merge('apachesolr_environment')
->key(array(
'env_id' => $environment['env_id'],
))
->fields($environment)
->execute();
db_delete('apachesolr_environment_variable')
->condition('env_id', $environment['env_id'])
->execute();
foreach ($conf as $name => $value) {
db_merge('apachesolr_environment_variable')
->key(array(
'env_id' => $environment['env_id'],
'name' => $name,
))
->fields(array(
'value' => serialize($value),
))
->execute();
}
foreach ($index_bundles as $entity_type => $bundles) {
apachesolr_index_set_bundles($environment['env_id'], $entity_type, $bundles);
}
apachesolr_environments_clear_cache();
}
function apachesolr_environments_clear_cache() {
cache_clear_all('apachesolr:environments', 'cache_apachesolr');
drupal_static_reset('apachesolr_load_all_environments');
drupal_static_reset('apachesolr_get_solr');
if (module_exists('ctools')) {
ctools_include('export');
ctools_export_load_object_reset('apachesolr_environment');
}
}
function apachesolr_environment_variable_get($env_id, $name, $default = NULL) {
$environment = apachesolr_environment_load($env_id);
if (isset($environment['conf'][$name])) {
return $environment['conf'][$name];
}
return $default;
}
function apachesolr_environment_variable_set($env_id, $name, $value) {
apachesolr_environment_save_to_database($env_id);
db_merge('apachesolr_environment_variable')
->key(array(
'env_id' => $env_id,
'name' => $name,
))
->fields(array(
'value' => serialize($value),
))
->execute();
apachesolr_environments_clear_cache();
}
function apachesolr_environment_variable_del($env_id, $name) {
apachesolr_environment_save_to_database($env_id);
db_delete('apachesolr_environment_variable')
->condition('env_id', $env_id)
->condition('name', $name)
->execute();
apachesolr_environments_clear_cache();
}
function apachesolr_environment_save_to_database($env_id) {
$environment = apachesolr_environment_load($env_id);
if (!empty($environment['in_code_only'])) {
apachesolr_environment_save($environment);
}
}
function apachesolr_server_status($url, $class = NULL) {
$status =& drupal_static(__FUNCTION__, array());
if (!interface_exists('DrupalApacheSolrServiceInterface')) {
require_once dirname(__FILE__) . '/apachesolr.interface.inc';
}
if (empty($class)) {
$class = variable_get('apachesolr_service_class', 'DrupalApacheSolrService');
}
$key = $url . '|' . $class;
if (!isset($status[$key])) {
$ping = FALSE;
try {
$solr = new $class($url);
$ping = @$solr
->ping(variable_get('apachesolr_ping_timeout', 4));
} catch (Exception $e) {
apachesolr_log_exception($url, $e);
}
$status[$key] = $ping;
}
return $status[$key];
}
function apachesolr_do_query(DrupalSolrQueryInterface $current_query) {
if (!is_object($current_query)) {
throw new Exception(t('NULL query object in function apachesolr_do_query()'));
}
$searcher = $current_query
->getSearcher();
if (module_exists('facetapi')) {
$adapter = facetapi_adapter_load($searcher);
if ($adapter) {
$adapter
->addActiveFilters($current_query);
}
}
foreach (module_implements('apachesolr_query_prepare') as $module) {
$function_name = $module . '_apachesolr_query_prepare';
$function_name($current_query);
}
$env_id = $current_query
->solr('getId');
$defType = apachesolr_environment_variable_get($env_id, 'apachesolr_query_type');
if (!empty($defType)) {
$current_query
->addParam('defType', $defType);
}
$query = apachesolr_current_query($env_id, $current_query);
if ($response = apachesolr_static_response_cache($searcher)) {
return array(
$query,
$response,
);
}
$query
->addParam('start', $query->page * $query
->getParam('rows'));
drupal_alter('apachesolr_query', $query);
if ($query->abort_search) {
return array(
NULL,
array(),
);
}
$keys = $query
->getParam('q');
if (strlen($keys) == 0 && ($filters = $query
->getFilters())) {
$qalt = array();
foreach ($filters as $delta => $filter) {
if (!$filter['#exclude'] && !$filter['#local']) {
$qalt[] = '(' . $query
->makeFilterQuery($filter) . ')';
$query
->removeFilter($filter['#name'], $filter['#value'], $filter['#exclude']);
}
}
if ($qalt) {
$query
->addParam('q.alt', implode(' AND ', $qalt));
}
}
$keys = htmlspecialchars($keys, ENT_NOQUOTES, 'UTF-8');
$keys = str_replace("'", ''', $keys);
$response = $query
->search($keys);
apachesolr_static_response_cache($searcher, $response);
return array(
$query,
$response,
);
}
function apachesolr_static_response_cache($searcher, $response = NULL) {
$_response =& drupal_static(__FUNCTION__, array());
if (is_object($response)) {
$_response[$searcher] = clone $response;
}
if (!isset($_response[$searcher])) {
$_response[$searcher] = NULL;
}
return $_response[$searcher];
}
function apachesolr_drupal_query($name, array $params = array(), $solrsort = '', $base_path = '', DrupalApacheSolrServiceInterface $solr = NULL, $context = array()) {
if (!interface_exists('DrupalSolrQueryInterface')) {
require_once dirname(__FILE__) . '/apachesolr.interface.inc';
}
$class_info = variable_get('apachesolr_query_class', array(
'file' => 'Solr_Base_Query',
'module' => 'apachesolr',
'class' => 'SolrBaseQuery',
));
$class = $class_info['class'];
if (!class_exists($class_info['class']) && isset($class_info['file']) && isset($class_info['module'])) {
module_load_include('php', $class_info['module'], $class_info['file']);
}
if (empty($solr)) {
$solr = apachesolr_get_solr();
}
return new $class($name, $solr, $params, $solrsort, $base_path, $context);
}
function apachesolr_drupal_subquery($operator = 'OR') {
if (!interface_exists('DrupalSolrQueryInterface')) {
require_once dirname(__FILE__) . '/apachesolr.interface.inc';
}
$class_info = variable_get('apachesolr_subquery_class', array(
'file' => 'Solr_Base_Query',
'module' => 'apachesolr',
'class' => 'SolrFilterSubQuery',
));
$class = $class_info['class'];
if (!class_exists($class_info['class']) && isset($class_info['file']) && isset($class_info['module'])) {
module_load_include('php', $class_info['module'], $class_info['file']);
}
$query = new $class($operator);
return $query;
}
function apachesolr_current_query($env_id, DrupalSolrQueryInterface $query = NULL) {
$saved_query =& drupal_static(__FUNCTION__, NULL);
if (is_object($query)) {
$saved_query[$env_id] = clone $query;
}
if (empty($saved_query[$env_id])) {
return NULL;
}
return is_object($saved_query[$env_id]) ? clone $saved_query[$env_id] : NULL;
}
function apachesolr_index_key($field) {
$index_type = !empty($field['index_type']) ? $field['index_type'] : NULL;
switch ($index_type) {
case 'text':
$type_prefix = 't';
break;
case 'text-omitNorms':
$type_prefix = 'to';
break;
case 'text-unstemmed':
$type_prefix = 'tu';
break;
case 'text-edgeNgram':
$type_prefix = 'te';
break;
case 'text-whiteSpace':
$type_prefix = 'tw';
break;
case 'integer':
$type_prefix = 'i';
break;
case 'half-int':
$type_prefix = 'h';
break;
case 'float':
$type_prefix = 'f';
break;
case 'double':
$type_prefix = 'p';
break;
case 'boolean':
$type_prefix = 'b';
break;
case 'tint':
$type_prefix = 'it';
break;
case 'thalf-int':
$type_prefix = 'ht';
break;
case 'tfloat':
$type_prefix = 'ft';
break;
case 'tdouble':
$type_prefix = 'pt';
break;
case 'sint':
$type_prefix = 'is';
break;
case 'half-sint':
$type_prefix = 'hs';
break;
case 'sfloat':
$type_prefix = 'fs';
break;
case 'sdouble':
$type_prefix = 'ps';
break;
case 'date':
$type_prefix = 'd';
break;
case 'date-deprecated':
$type_prefix = 'dd';
break;
case 'binary':
$type_prefix = 'x';
break;
case 'storage':
$type_prefix = 'z';
break;
case 'point':
$type_prefix = 'point';
break;
case 'location':
$type_prefix = 'loc';
break;
case 'geohash':
$type_prefix = 'geo';
break;
case 'string':
default:
$type_prefix = 's';
}
$sm = !empty($field['multiple']) ? 'm_' : 's_';
$apachesolr_field_length_limit = variable_get('apachesolr_field_length_limit', '32');
if ($apachesolr_field_length_limit <= 0) {
return $type_prefix . $sm . $field['name'];
}
else {
return substr($type_prefix . $sm . $field['name'], 0, $apachesolr_field_length_limit);
}
}
function apachesolr_field_name_map($field_name) {
$map =& drupal_static(__FUNCTION__);
if (!isset($map)) {
$map = array(
'content' => t('The full, rendered content (e.g. the rendered node body)'),
'ts_comments' => t('The rendered comments associated with a node'),
'tos_content_extra' => t('Extra rendered content or keywords'),
'tos_name_formatted' => t('Author name (Formatted)'),
'label' => t('Title or label'),
'teaser' => t('Teaser or preview'),
'tos_name' => t('Author name'),
'path_alias' => t('Path alias'),
'taxonomy_names' => t('All taxonomy term names'),
'tags_h1' => t('Body text inside H1 tags'),
'tags_h2_h3' => t('Body text inside H2 or H3 tags'),
'tags_h4_h5_h6' => t('Body text inside H4, H5, or H6 tags'),
'tags_inline' => t('Body text in inline tags like EM or STRONG'),
'tags_a' => t('Body text inside links (A tags)'),
'tid' => t('Taxonomy term IDs'),
'is_uid' => t('User IDs'),
'bundle' => t('Content type names eg. article'),
'entity_type' => t('Entity type names eg. node'),
'ss_language' => t('Language type eg. en or und (undefinded)'),
);
if (module_exists('taxonomy')) {
foreach (taxonomy_get_vocabularies() as $vocab) {
$map['tm_vid_' . $vocab->vid . '_names'] = t('Taxonomy term names only from the %name vocabulary', array(
'%name' => $vocab->name,
));
$map['im_vid_' . $vocab->vid] = t('Taxonomy term IDs from the %name vocabulary', array(
'%name' => $vocab->name,
));
}
}
foreach (apachesolr_entity_fields('node') as $field_nm => $nodefields) {
foreach ($nodefields as $field_info) {
$map[apachesolr_index_key($field_info)] = t('Field of type @type: %label', array(
'@type' => $field_info['field']['type'],
'%label' => $field_info['display_name'],
));
}
}
drupal_alter('apachesolr_field_name_map', $map);
}
return isset($map[$field_name]) ? $map[$field_name] : $field_name;
}
function apachesolr_facet_form_validate($form, &$form_state) {
if ($form_state['values']['global']['operator'] == FACETAPI_OPERATOR_OR && $form_state['values']['global']['facet_missing']) {
form_set_error('operator', t('Apache Solr does not support <em>facet missing</em> in combination with the OR operator.'));
}
}
function apachesolr_module_implements_alter(&$implementations, $hook) {
if ($hook == 'entity_info_alter') {
$group = $implementations['apachesolr'];
unset($implementations['apachesolr']);
$implementations['apachesolr'] = $group;
}
}
function apachesolr_entity_info_alter(&$entity_info) {
$environments = apachesolr_load_all_environments();
$default_entity_info = array();
$default_entity_info['node']['indexable'] = TRUE;
$default_entity_info['node']['status callback'][] = 'apachesolr_index_node_status_callback';
$default_entity_info['node']['document callback'][] = 'apachesolr_index_node_solr_document';
$default_entity_info['node']['reindex callback'] = 'apachesolr_index_node_solr_reindex';
$default_entity_info['node']['bundles changed callback'] = 'apachesolr_index_node_bundles_changed';
$default_entity_info['node']['index_table'] = 'apachesolr_index_entities_node';
$default_entity_info['node']['cron_check'] = 'apachesolr_index_node_check_table';
drupal_alter('apachesolr_entity_info', $default_entity_info);
foreach (array_keys($entity_info) as $type) {
if (!isset($entity_info[$type]['apachesolr'])) {
$entity_info[$type]['apachesolr'] = array();
}
if (isset($default_entity_info[$type])) {
$entity_info[$type]['apachesolr'] += $default_entity_info[$type];
}
$default = array(
'indexable' => FALSE,
'status callback' => '',
'document callback' => '',
'reindex callback' => '',
'bundles changed callback' => '',
);
$entity_info[$type]['apachesolr'] += $default;
}
foreach ($entity_info as $entity_type => $info) {
if ($info['apachesolr']['indexable']) {
foreach ($environments as $env) {
if (empty($env['env_id']['conf']['apachesolr_read_only'])) {
$supported = apachesolr_get_index_bundles($env['env_id'], $entity_type);
foreach (array_keys($info['bundles']) as $bundle) {
if (in_array($bundle, $supported)) {
$entity_info[$entity_type]['bundles'][$bundle]['apachesolr']['index'] = TRUE;
}
}
}
}
}
}
}
function apachesolr_get_index_bundles($env_id, $entity_type) {
$environment = apachesolr_environment_load($env_id);
return !empty($environment['index_bundles'][$entity_type]) ? $environment['index_bundles'][$entity_type] : array();
}
function apachesolr_entity_insert($entity, $type) {
if (isset($entity->status) && $entity->status) {
return apachesolr_entity_update($entity, $type);
}
}
function apachesolr_entity_should_index($entity, $type) {
$info = entity_get_info($type);
list($id, $vid, $bundle) = entity_extract_ids($type, $entity);
if ($bundle && isset($info['bundles'][$bundle]['apachesolr']['index']) && $info['bundles'][$bundle]['apachesolr']['index']) {
return TRUE;
}
return FALSE;
}
function apachesolr_entity_update($entity, $type) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
if (apachesolr_entity_should_index($entity, $type)) {
list($id, $vid, $bundle) = entity_extract_ids($type, $entity);
$status_callbacks = apachesolr_entity_get_callback($type, 'status callback', $bundle);
$status = TRUE;
if (is_array($status_callbacks)) {
foreach ($status_callbacks as $status_callback) {
if (is_callable($status_callback)) {
$status = $status && $status_callback($id, $type, $entity);
}
}
}
if (!$status) {
apachesolr_entity_delete($entity, $type);
return NULL;
}
$indexer_table = apachesolr_get_indexer_table($type);
db_merge($indexer_table)
->key(array(
'entity_type' => $type,
'entity_id' => $id,
))
->fields(array(
'bundle' => $bundle,
'status' => 1,
'changed' => REQUEST_TIME,
))
->execute();
}
}
function apachesolr_get_indexer_table($type) {
$entity_info = entity_get_info();
if (isset($entity_info[$type]['apachesolr']['index_table'])) {
$indexer_table = $entity_info[$type]['apachesolr']['index_table'];
}
else {
$indexer_table = 'apachesolr_index_entities';
}
return $indexer_table;
}
function apachesolr_entity_delete($entity, $entity_type) {
list($entity_id) = entity_extract_ids($entity_type, $entity);
if (apachesolr_entity_should_index($entity, $entity_type)) {
$environments = apachesolr_load_all_environments();
foreach ($environments as $environment) {
apachesolr_remove_entity($environment['env_id'], $entity_type, $entity_id);
}
}
}
function apachesolr_remove_entity($env_id, $entity_type, $entity_id) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$indexer_table = apachesolr_get_indexer_table($entity_type);
if (apachesolr_index_delete_entity_from_index($env_id, $entity_type, $entity_id)) {
db_delete($indexer_table)
->condition('entity_type', $entity_type)
->condition('entity_id', $entity_id)
->execute();
}
else {
db_update($indexer_table)
->condition('entity_id', $entity_id)
->fields(array(
'changed' => REQUEST_TIME,
'status' => 0,
))
->execute();
}
}
function apachesolr_entity_fields($entity_type = 'node') {
$fields =& drupal_static(__FUNCTION__, array());
if (!isset($fields[$entity_type])) {
$fields[$entity_type] = array();
$mappings = apachesolr_get_field_mappings($entity_type);
$modules = system_get_info('module');
$instances = field_info_instances($entity_type);
foreach (field_info_fields() as $field_name => $field) {
$row = array();
if (isset($field['bundles'][$entity_type]) && (isset($mappings['per-field'][$field_name]) || isset($mappings[$field['type']]))) {
if (isset($mappings['per-field'][$field_name])) {
$row = $mappings['per-field'][$field_name];
}
else {
$row = $mappings[$field['type']];
}
$row['field'] = $field;
if ($row['field']['cardinality'] != 1) {
$row['multiple'] = TRUE;
}
$function = !empty($row['name callback']) ? $row['name callback'] : NULL;
if ($function && is_callable($function)) {
$row['name'] = $function($field);
}
else {
$row['name'] = $field['field_name'];
}
$row['module_name'] = $modules[$field['module']]['name'];
$display_name = array();
foreach ($field['bundles'][$entity_type] as $bundle) {
$field_display = isset($instances[$bundle][$field_name]['display']) ? $instances[$bundle][$field_name]['display'] : array();
if (empty($field_display['search_index']) || isset($field_display['search_index']['type']) && $field_display['search_index']['type'] != 'hidden') {
$row['display_name'] = $instances[$bundle][$field_name]['label'];
$row['bundles'][] = $bundle;
}
}
if (!empty($row['bundles'])) {
$fields[$entity_type][apachesolr_index_key($row)][] = $row;
}
}
}
}
return $fields[$entity_type];
}
function apachesolr_get_field_mappings($entity_type) {
$field_mappings =& drupal_static(__FUNCTION__, array());
if (!isset($field_mappings[$entity_type])) {
$field_mappings[$entity_type] = module_invoke_all('apachesolr_field_mappings');
$mappings =& $field_mappings[$entity_type];
foreach (array_keys($mappings) as $key) {
$defaults = array(
'dependency plugins' => array(
'bundle',
'role',
),
'map callback' => FALSE,
'name callback' => '',
'hierarchy callback' => FALSE,
'indexing_callback' => '',
'index_type' => 'string',
'facets' => FALSE,
'facet missing allowed' => FALSE,
'facet mincount allowed' => FALSE,
'multiple' => TRUE,
);
if ($key !== 'per-field') {
$mappings[$key] += $defaults;
}
else {
foreach (array_keys($field_mappings[$entity_type][$key]) as $field_key) {
$mappings[$key][$field_key] += $defaults;
}
}
}
drupal_alter('apachesolr_field_mappings', $mappings, $entity_type);
}
return $field_mappings[$entity_type];
}
function field_apachesolr_index_document_build(ApacheSolrDocument $document, $entity, $entity_type) {
$info = entity_get_info($entity_type);
if ($info['fieldable']) {
$indexed_fields = apachesolr_entity_fields($entity_type);
foreach ($indexed_fields as $index_key => $nodefields) {
foreach ($nodefields as $field_info) {
$field_name = $field_info['field']['field_name'];
if (isset($entity->{$field_name})) {
$functions = $field_info['indexing_callback'];
if (!is_array($functions)) {
$functions = array(
$functions,
);
}
foreach ($functions as $function) {
if ($function && function_exists($function)) {
$fields = $function($entity, $field_name, $index_key, $field_info);
foreach ($fields as $field) {
$document
->setMultiValue($field['key'], $field['value']);
}
}
}
}
}
}
}
}
function apachesolr_apachesolr_index_document_build_node(ApacheSolrDocument $document, $entity, $env_id) {
if (!empty($entity->book['bid'])) {
$document->is_book_bid = (int) $entity->book['bid'];
}
}
function apachesolr_clean_text($text) {
$text = preg_replace('@<(applet|audio|canvas|command|embed|iframe|map|menu|noembed|noframes|noscript|script|style|svg|video)[^>]*>.*</\\1>@siU', ' ', $text);
$text = filter_xss(str_replace(array(
'<',
'>',
), array(
' <',
'> ',
), $text), array());
$text = htmlspecialchars(html_entity_decode($text, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
$text = preg_replace('/\\s+/s', ' ', $text);
$text = preg_replace('/\\s(\\p{Pc}|\\p{Pd}|\\p{Pe}|\\p{Pf}|!|\\?|,|\\.|:|;)/s', '$1', $text);
$text = preg_replace('/(\\p{Ps}|¿|¡)\\s/s', '$1', $text);
return $text;
}
function apachesolr_fields_list_facet_map_callback($facets, $options) {
$map = array();
$allowed_values = array();
$fields = field_info_fields();
$field_name = $options['field']['field_name'];
if (isset($fields[$field_name])) {
$allowed_values = list_allowed_values($fields[$field_name]);
}
if ($fields[$field_name]['type'] == 'list_boolean') {
foreach ($allowed_values as $key => $value) {
$strkey = $key ? 'true' : 'false';
$allowed_values[$strkey] = $value;
unset($allowed_values[$key]);
}
}
foreach ($facets as $key) {
if (isset($allowed_values[$key])) {
$map[$key]['#markup'] = field_filter_xss($allowed_values[$key]);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#markup'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#markup'] = field_filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_nodereference_map_callback($facets, $options) {
$map = array();
$allowed_values = array();
$fields = field_info_fields();
$field_name = $options['field']['field_name'];
if (isset($fields[$field_name])) {
$allowed_values = node_reference_potential_references($fields[$field_name]);
}
foreach ($facets as $key) {
if (isset($allowed_values[$key])) {
$map[$key]['#markup'] = field_filter_xss($allowed_values[$key]['title']);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#markup'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#markup'] = field_filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_userreference_map_callback($facets, $options) {
$map = array();
$allowed_values = array();
$fields = field_info_fields();
$field_name = $options['field']['field_name'];
if (isset($fields[$field_name])) {
$allowed_values = user_reference_potential_references($fields[$field_name]);
}
foreach ($facets as $key) {
if (isset($allowed_values[$key])) {
$map[$key]['#markup'] = field_filter_xss($allowed_values[$key]['title']);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#markup'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#markup'] = field_filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_entityreference_facet_map_callback(array $values, array $options) {
$map = array();
$entity_ids = array();
foreach ($values as $value) {
list($entity_type, $id) = explode(':', $value);
$entity_ids[$entity_type][] = $id;
}
foreach ($entity_ids as $entity_type => $ids) {
$entities = entity_load($entity_type, $ids);
foreach ($entities as $id => $entity) {
$key = $entity_type . ':' . $id;
$map[$key] = entity_label($entity_type, $entity);
}
}
return $map;
}
function apachesolr_entity_get_callback($entity_type, $callback, $bundle = NULL) {
$info = entity_get_info($entity_type);
if ($bundle && isset($info['bundles'][$bundle]['apachesolr'][$callback])) {
$callback_function = $info['bundles'][$bundle]['apachesolr'][$callback];
}
elseif (isset($info['apachesolr'][$callback])) {
$callback_function = $info['apachesolr'][$callback];
}
else {
$callback_function = NULL;
}
return $callback_function;
}
function apachesolr_get_nodes_to_index($namespace, $limit) {
$env_id = apachesolr_default_environment();
module_load_include('inc', 'apachesolr', 'apachesolr.index');
apachesolr_index_get_entities_to_index($env_id, 'node', $limit);
}
function apachesolr_theme() {
return array(
'apachesolr_sort_list' => array(
'variables' => array(
'items' => NULL,
),
),
'apachesolr_sort_link' => array(
'variables' => array(
'text' => NULL,
'path' => NULL,
'options' => NULL,
'active' => FALSE,
'direction' => '',
),
),
'apachesolr_settings_title' => array(
'variables' => array(
'env_id' => NULL,
),
),
);
}
function apachesolr_hook_info() {
$hooks = array(
'apachesolr_field_mappings' => array(
'group' => 'apachesolr',
),
'apachesolr_field_mappings_alter' => array(
'group' => 'apachesolr',
),
'apachesolr_query_prepare' => array(
'group' => 'apachesolr',
),
'apachesolr_query_alter' => array(
'group' => 'apachesolr',
),
'apachesolr_search_result_alter' => array(
'group' => 'apachesolr',
),
'apachesolr_environment_delete' => array(
'group' => 'apachesolr',
),
);
$hooks['apachesolr_index_document_build'] = array(
'group' => 'apachesolr',
);
return $hooks;
}
function field_apachesolr_field_mappings() {
$mappings = array(
'list_integer' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'map callback' => 'apachesolr_fields_list_facet_map_callback',
'index_type' => 'integer',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet missing allowed' => TRUE,
),
'list_float' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'map callback' => 'apachesolr_fields_list_facet_map_callback',
'index_type' => 'float',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet missing allowed' => TRUE,
),
'list_text' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'map callback' => 'apachesolr_fields_list_facet_map_callback',
'index_type' => 'string',
'facets' => TRUE,
'facet missing allowed' => TRUE,
),
'list_boolean' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'map callback' => 'apachesolr_fields_list_facet_map_callback',
'index_type' => 'boolean',
'facets' => TRUE,
'facet missing allowed' => TRUE,
),
'number_integer' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'index_type' => 'tint',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
'number_decimal' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'index_type' => 'tfloat',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
'number_float' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'index_type' => 'tfloat',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
'taxonomy_term_reference' => array(
'map callback' => 'facetapi_map_taxonomy_terms',
'hierarchy callback' => 'facetapi_get_taxonomy_hierarchy',
'indexing_callback' => array(
'apachesolr_term_reference_indexing_callback',
),
'index_type' => 'integer',
'facet_block_callback' => 'apachesolr_search_taxonomy_facet_block',
'facets' => TRUE,
'query types' => array(
'term',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
'text' => array(
'indexing_callback' => array(
'apachesolr_fields_default_indexing_callback',
),
'index_type' => 'string',
'facets' => TRUE,
'facet missing allowed' => TRUE,
),
);
return $mappings;
}
function date_apachesolr_field_mappings() {
$mappings = array();
$default = array(
'indexing_callback' => array(
'apachesolr_date_default_indexing_callback',
),
'index_type' => 'date',
'facets' => TRUE,
'query types' => array(
'date',
),
'query type' => 'date',
'min callback' => 'apachesolr_get_min_date',
'max callback' => 'apachesolr_get_max_date',
'map callback' => 'facetapi_map_date',
);
$mappings['date'] = $default;
$mappings['datetime'] = $default;
$mappings['datestamp'] = $default;
$mappings['datestamp']['indexing_callback'] = array(
'apachesolr_datestamp_default_indexing_callback',
);
return $mappings;
}
function apachesolr_get_min_date(array $facet) {
$table = 'field_data_' . $facet['field api name'];
$column = $facet['field api name'] . '_value';
$query = db_select($table, 't');
$query
->addExpression('MIN(' . $column . ')', 'min');
$query_min = $query
->execute()
->fetch()->min;
if (is_numeric($query_min)) {
$return = (int) $query_min;
}
else {
$return = strtotime($query_min);
if ($return === FALSE) {
$return = 1;
}
}
return $return;
}
function apachesolr_get_max_date(array $facet) {
$table = 'field_data_' . $facet['field api name'];
$column = $facet['field api name'] . '_value';
$query = db_select($table, 't');
$query
->addExpression('MAX(' . $column . ')', 'max');
$query_max = $query
->execute()
->fetch()->max;
if (is_numeric($query_max)) {
$return = (int) $query_max;
}
else {
$return = strtotime($query_max);
if ($return === FALSE) {
$return = time() + 52 * 7 * 24 * 60 * 60;
}
}
return $return;
}
function node_reference_apachesolr_field_mappings() {
$mappings = array(
'node_reference' => array(
'indexing_callback' => array(
'apachesolr_nodereference_indexing_callback',
),
'index_type' => 'integer',
'map callback' => 'apachesolr_nodereference_map_callback',
'facets' => TRUE,
),
);
return $mappings;
}
function user_reference_apachesolr_field_mappings() {
$mappings = array(
'user_reference' => array(
'indexing_callback' => array(
'apachesolr_userreference_indexing_callback',
),
'index_type' => 'integer',
'map callback' => 'apachesolr_userreference_map_callback',
'facets' => TRUE,
),
);
return $mappings;
}
function entityreference_apachesolr_field_mappings() {
$mappings = array(
'entityreference' => array(
'indexing_callback' => array(
'apachesolr_entityreference_indexing_callback',
),
'map callback' => 'apachesolr_entityreference_facet_map_callback',
'index_type' => 'string',
'facets' => TRUE,
'query types' => array(
'term',
),
'facet missing allowed' => TRUE,
),
);
return $mappings;
}
function apachesolr_l($text, $path, $options = array()) {
$options += array(
'attributes' => array(),
'html' => FALSE,
'query' => array(),
);
unset($options['attributes']['title']);
$get = array_diff_key($_GET, array(
'q' => 1,
'page' => 1,
'solrsort' => 1,
), $options['query']);
$options['query'] += $get;
return '<a href="' . check_url(url($path, $options)) . '"' . drupal_attributes($options['attributes']) . '>' . ($options['html'] ? $text : check_plain(html_entity_decode($text))) . '</a>';
}
function theme_apachesolr_sort_link($vars) {
$icon = '';
if ($vars['direction']) {
$icon = ' ' . theme('tablesort_indicator', array(
'style' => $vars['direction'],
));
}
if ($vars['active']) {
$vars['options']['attributes']['class'][] = 'active';
}
return $icon . apachesolr_l($vars['text'], $vars['path'], $vars['options']);
}
function theme_apachesolr_sort_list($vars) {
$vars['items'] = array_values($vars['items']);
return theme('item_list', array(
'items' => $vars['items'],
));
}
function theme_apachesolr_settings_title($vars) {
$output = '';
if ($environment = apachesolr_environment_load($vars['env_id'])) {
$url = url('admin/config/search/apachesolr/settings/', array(
'query' => array(
'destination' => current_path(),
),
));
$output .= '<h3>';
$output .= t('Settings for: @environment (<a href="@url">Overview</a>)', array(
'@url' => $url,
'@environment' => $environment['name'],
));
$output .= "</h3>\n";
}
return $output;
}
function apachesolr_environment_load_subrecords(&$environments) {
if (empty($environments)) {
return NULL;
}
$all_index_bundles = db_select('apachesolr_index_bundles', 'ib')
->fields('ib', array(
'env_id',
'entity_type',
'bundle',
))
->condition('env_id', array_keys($environments), 'IN')
->orderBy('env_id')
->orderBy('entity_type')
->orderBy('bundle')
->execute()
->fetchAll(PDO::FETCH_ASSOC);
$all_index_bundles_keyed = array();
foreach ($all_index_bundles as $env_info) {
extract($env_info);
$all_index_bundles_keyed[$env_id][$entity_type][$bundle] = $bundle;
}
$all_variables = db_select('apachesolr_environment_variable', 'v')
->fields('v', array(
'env_id',
'name',
'value',
))
->condition('env_id', array_keys($environments), 'IN')
->orderBy('env_id')
->orderBy('name')
->orderBy('value')
->execute()
->fetchAll(PDO::FETCH_ASSOC);
$variables = array();
foreach ($all_variables as $variable) {
extract($variable);
$variables[$env_id][$name] = unserialize($value);
}
foreach ($environments as $env_id => &$environment) {
$index_bundles = !empty($all_index_bundles_keyed[$env_id]) ? $all_index_bundles_keyed[$env_id] : array();
$conf = !empty($variables[$env_id]) ? $variables[$env_id] : array();
if (is_array($environment)) {
if (!empty($environment['index_bundles']) && !empty($index_bundles) && $environment['index_bundles'] !== $index_bundles) {
unset($environment['in_code_only']);
$environment['type'] = 'Overridden';
}
if (!empty($environment['conf']) && !empty($conf) && !apachesolr_environment_conf_equals($environment['conf'], $conf)) {
unset($environment['in_code_only']);
$environment['type'] = 'Overridden';
}
$environment['index_bundles'] = empty($environment['index_bundles']) || !empty($index_bundles) ? $index_bundles : $environment['index_bundles'];
$environment['conf'] = empty($environment['conf']) || !empty($conf) ? $conf : $environment['conf'];
}
elseif (is_object($environment)) {
if ($environment->index_bundles !== $index_bundles && !empty($index_bundles)) {
unset($environment->in_code_only);
$environment->type = 'Overridden';
}
if (!apachesolr_environment_conf_equals($environment->conf, $conf) && !empty($conf)) {
unset($environment->in_code_only);
$environment->type = 'Overridden';
}
$environment->index_bundles = empty($environment->index_bundles) || !empty($index_bundles) ? $index_bundles : $environment->index_bundles;
$environment->conf = empty($environment->conf) || !empty($conf) ? $conf : $environment->conf;
}
}
}
function apachesolr_environment_conf_equals(array $conf1, array $conf2, $ignore_state = TRUE) {
if ($ignore_state === TRUE) {
$state_variables = apachesolr_environment_conf_state_variables();
$conf1 = array_diff_key($conf1, $state_variables);
$conf2 = array_diff_key($conf2, $state_variables);
}
return $conf1 === $conf2;
}
function apachesolr_environment_conf_state_variables() {
$keys =& drupal_static(__FUNCTION__);
if (!isset($keys)) {
$_keys = array(
'apachesolr_index_last',
'apachesolr_index_updated',
'apachesolr_last_optimize_attempt',
'apachesolr_last_optimize_success',
);
$keys = array_combine($_keys, $_keys);
}
return $keys;
}
function apachesolr_ctools_environment_save($environment) {
apachesolr_environment_save((array) $environment);
}
function apachesolr_ctools_environment_delete($env_id) {
if (is_object($env_id) || is_array($env_id)) {
$env_id = (object) $env_id;
$env_id = $env_id->env_id;
}
apachesolr_environment_delete($env_id);
}
function apachesolr_ctools_environment_export($environment, $indent) {
ctools_include('export');
$environment = (object) $environment;
$environment = (object) apachesolr_environment_load($environment->env_id);
$index_bundles = array();
foreach (entity_get_info() as $type => $info) {
if ($bundles = apachesolr_get_index_bundles($environment->env_id, $type)) {
$index_bundles[$type] = $bundles;
}
}
$state_variables = apachesolr_environment_conf_state_variables();
foreach ($state_variables as $key) {
unset($environment->conf[$key]);
}
$additions_top = array();
$additions_bottom = array(
'conf' => $environment->conf,
'index_bundles' => $index_bundles,
);
return ctools_export_object('apachesolr_environment', $environment, $indent, NULL, $additions_top, $additions_bottom);
}
function apachesolr_log_exception($env_id, $exception) {
$backtrace = $exception
->getTrace();
$caller = _drupal_get_last_caller($backtrace);
watchdog('Apache Solr', 'Exception caught for function %function (line %line of %file), Environment @env_id: ' . nl2br(check_plain($exception
->getMessage())), array(
'%function' => $caller['function'],
'%file' => $caller['file'],
'%line' => $caller['line'],
'@env_id' => $env_id,
), WATCHDOG_ERROR);
}