View source
<?php
define('APACHESOLR_READ_WRITE', 0);
define('APACHESOLR_READ_ONLY', 1);
define('APACHESOLR_API_VERSION', '3.0');
define('APACHESOLR_REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
function apachesolr_init() {
if (arg(0) == 'admin') {
drupal_add_css(drupal_get_path('module', 'apachesolr') . '/apachesolr.css');
}
if (!function_exists('json_decode')) {
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
require_once 'Zend/Json/Decoder.php';
require_once 'Zend/Json/Encoder.php';
function json_decode($string, $assoc = FALSE) {
if ($assoc) {
$objectDecodeType = Zend_Json::TYPE_ARRAY;
}
else {
$objectDecodeType = Zend_Json::TYPE_OBJECT;
}
return Zend_Json_Decoder::decode($string, $objectDecodeType);
}
function json_encode($data) {
return Zend_Json_Encoder::encode($data, $objectDecodeType);
}
}
}
function apachesolr_menu() {
$items = array();
$items['admin/settings/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/settings/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/settings/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/settings/apachesolr/settings/';
$items[$settings_path . '%apachesolr_environment/index'] = array(
'title' => 'Index',
'page callback' => 'apachesolr_status_page',
'page arguments' => array(
4,
),
'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' => 'apachesolr_status_page',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'apachesolr_index_action_form_remaining_confirm',
4,
),
'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',
4,
),
'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',
4,
),
'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',
4,
),
'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',
4,
),
'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',
4,
),
'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',
4,
),
'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',
4,
),
'access callback' => 'apachesolr_environment_delete_page_access',
'access arguments' => array(
'administer search',
4,
),
'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',
);
$items['admin/settings/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/settings/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,
4,
),
'weight' => -5,
'access arguments' => array(
'administer search',
),
'file path' => $file_path,
'file' => 'facetapi.admin.inc',
'type' => MENU_LOCAL_TASK,
);
}
else {
$items[$settings_path . '%apachesolr_environment/facets/' . $realm_name] = array(
'title' => $realm['label'],
'page callback' => 'apachesolr_enabled_facets_page',
'page arguments' => array(
$realm_name,
4,
),
'weight' => -5,
'access arguments' => array(
'administer search',
),
'type' => MENU_LOCAL_TASK,
'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'] = theme('apachesolr_settings_title', $env_id);
$page['settings'] = drupal_get_form('facetapi_realm_settings_form', $searcher, $realm_name);
$build_output = NULL;
foreach ($page as $build_result) {
$build_output .= $build_result;
}
return $build_output;
}
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',
'parent' => 'adapter',
'path' => drupal_get_path('module', 'apachesolr') . '/plugins/facetapi',
'file' => 'adapter.inc',
),
),
);
}
function apachesolr_facetapi_query_types() {
$path = drupal_get_path('module', 'apachesolr') . '/plugins/facetapi';
return array(
'apachesolr_term' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiTerm',
'parent' => 'query_type',
'file' => 'query_type_term.inc',
'path' => $path,
'adapter' => 'apachesolr',
),
),
'apachesolr_date' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiDate',
'parent' => 'date',
'file' => 'query_type_date.inc',
'path' => $path,
'adapter' => 'apachesolr',
),
),
'apachesolr_numeric_range' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiNumericRange',
'parent' => 'range',
'file' => 'query_type_numeric_range.inc',
'path' => $path,
'adapter' => 'apachesolr',
),
),
'apachesolr_geo' => array(
'handler' => array(
'class' => 'ApacheSolrFacetapiGeo',
'parent' => 'date',
'file' => 'query_type_geo.inc',
'path' => $path,
'adapter' => 'apachesolr',
),
),
);
}
function apachesolr_facetapi_facet_info($searcher_info) {
$facets = array();
if ('apachesolr' == $searcher_info['adapter']) {
$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 of type @type.', array(
'@type' => $field_info['field']['type'],
)),
'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'];
}
}
}
}
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')) {
drupal_set_message(t("%search_name is not available. Your search is being redirected.", array(
'%search_name' => $search_name,
)));
drupal_goto('search/node/' . drupal_urlencode($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)) {
$query = "UPDATE {{$table}} asn SET asn.changed = '%s' WHERE asn.entity_id = '%s'";
db_query($query, array(
APACHESOLR_REQUEST_TIME,
$entity_id,
));
}
}
function apachesolr_user($op, &$edit, &$account) {
switch ($op) {
case 'update':
if (isset($edit['name']) && $account->name != $edit['name']) {
$table = apachesolr_get_indexer_table('node');
$query = "UPDATE {{$table}} asn\n INNER JOIN {node} n ON asn.entity_id = n.nid SET asn.changed = '%s'\n WHERE n.uid = '%s'";
$result = db_query($query, array(
APACHESOLR_REQUEST_TIME,
$account->uid,
));
}
break;
}
}
function apachesolr_taxonomy($op, $type, $edit) {
if ($type == 'term' && $op == 'update') {
$table = apachesolr_get_indexer_table('node');
$query = "UPDATE {{$table}} asn\n INNER JOIN {term_node} tn ON asn.entity_id = tn.nid SET asn.changed = '%s'\n WHERE tn.tid ='%s'";
$result = db_query($query, array(
APACHESOLR_REQUEST_TIME,
$term->tid,
));
}
}
function apachesolr_comment($edit, $op) {
$edit = (array) $edit;
switch ($op) {
case 'insert':
case 'update':
case 'delete':
case 'publish':
case 'unpublish':
apachesolr_mark_entity('node', $edit['nid']);
break;
}
}
function apachesolr_node_type($op, $info) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
$env_id = apachesolr_default_environment();
if ($op == 'delete') {
$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,
));
$callback = apachesolr_entity_get_callback('node', 'bundles changed callback');
if (!empty($callback)) {
call_user_func($callback, $env_id, $existing_bundles, $new_bundles);
}
}
elseif ($op == 'insert') {
$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);
}
}
}
elseif (!empty($info->old_type) && $info->old_type != $info->type) {
$table = apachesolr_get_indexer_table('node');
$query = "UPDATE {{$table}} asn\n INNER JOIN {node} n ON asn.entity_id = n.nid SET asn.changed = '%s'\n WHERE (n.type = '%s' OR n.type = '%s')";
db_query($query, array(
APACHESOLR_REQUEST_TIME,
$info->type,
$info->old_type,
));
db_query("UPDATE {apachesolr_index_bundles} SET bundle = '%s' WHERE bundle = '%s' AND entity_type = '%s'", array(
$info->type,
$info->old_type,
'node',
));
}
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) {
watchdog('Apache Solr', nl2br(check_plain($e
->getMessage())), NULL, WATCHDOG_ERROR);
drupal_set_message(nl2br(check_plain($e
->getMessage())), 'warning');
}
}
function apachesolr_set_stats_message($text, $type = 'status', $repeat = FALSE) {
try {
$solr = apachesolr_get_solr();
$stats_summary = $solr
->getStatsSummary();
drupal_set_message(check_plain(t($text, $stats_summary)), $type, FALSE);
} catch (Exception $e) {
watchdog('Apache Solr', nl2br(check_plain($e
->getMessage())), NULL, WATCHDOG_ERROR);
}
}
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);
$time = APACHESOLR_REQUEST_TIME;
foreach ($environments as $env_id) {
$last = apachesolr_environment_variable_get($env_id, 'apachesolr_last_optimize', 0);
if (apachesolr_environment_variable_get($env_id, 'apachesolr_read_only', APACHESOLR_READ_WRITE) == APACHESOLR_READ_ONLY) {
continue;
}
$bundles = apachesolr_get_index_bundles($env_id, 'node');
if (empty($bundles)) {
continue;
}
$callbacks = apachesolr_get_index_callbacks();
if (isset($callbacks['node']['cron_check'])) {
$callback = $callbacks['node']['cron_check'];
call_user_func($callback);
}
try {
$solr = apachesolr_get_solr($env_id);
if ($optimize_interval && $time - $last > $optimize_interval) {
$solr
->optimize(FALSE, FALSE);
apachesolr_environment_variable_set($env_id, 'apachesolr_last_optimize', $time);
apachesolr_set_last_index_updated($env_id, $time);
}
$updated = apachesolr_get_last_index_updated($env_id);
if ($updated > 0) {
$solr
->clearCache();
$solr
->getLuke();
if ($time - $updated >= variable_get('apachesolr_cache_delay', 300)) {
apachesolr_set_last_index_updated($env_id);
}
}
} catch (Exception $e) {
watchdog('Apache Solr', nl2br(check_plain($e
->getMessage())) . ' in apachesolr_cron', NULL, WATCHDOG_ERROR);
}
$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/settings/apachesolr/settings/' . $env_id);
$breadcrumb[] = l($realm['label'], 'admin/settings/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) {
static $_searched = 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) {
static $_suppress = 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, $reset = FALSE) {
static $default_env_id;
if ($reset) {
$default_env_id = 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, $reset = FALSE) {
static $solr_cache;
if ($reset) {
$solr_cache = array();
return;
}
$environments = apachesolr_load_all_environments();
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_info = array();
$class = NULL;
if ($environments[$env_id]['service_class']) {
$class_info = isset($environments[$env_id]['conf']['service_class_info']) ? $environments[$env_id]['conf']['service_class_info'] : NULL;
$class = $environments[$env_id]['service_class'];
}
$class = apachesolr_load_service_class($class, $class_info);
if (empty($solr_cache[$env_id])) {
$solr = new $class($environments[$env_id]['url'], $env_id);
$solr_cache[$env_id] = $solr;
}
return $solr_cache[$env_id];
}
else {
throw new Exception('No default Apache Solr environment.');
}
}
function apachesolr_load_service_class($class = NULL, $class_info = NULL) {
if (!interface_exists('DrupalApacheSolrServiceInterface')) {
require_once dirname(__FILE__) . '/apachesolr.interface.inc';
}
if (!is_array($class_info) || !isset($class)) {
$class_info = variable_get('apachesolr_service_class', array(
'file' => 'Drupal_Apache_Solr_Service',
'module' => 'apachesolr',
'class' => 'DrupalApacheSolrService',
));
$class = $class_info['class'];
}
if (class_exists($class)) {
return $class;
}
if (isset($class_info['file']) && isset($class_info['module'])) {
$loaded = module_load_include('php', $class_info['module'], $class_info['file']);
if ($loaded === FALSE) {
throw new Exception('Could not load defined service class: ' . $class);
}
}
return $class;
}
function apachesolr_load_all_environments($reset = FALSE) {
static $environments;
if ($reset) {
$environments = NULL;
cache_clear_all('apachesolr:environments', 'cache_apachesolr');
if (module_exists('ctools')) {
ctools_include('export');
ctools_export_load_object_reset('apachesolr_environment');
}
return;
}
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_results = db_query('SELECT * FROM {apachesolr_environment}');
while ($environment_result = db_fetch_array($environments_results)) {
$environments[$environment_result['env_id']] = $environment_result;
}
}
apachesolr_environment_load_subrecords($environments);
cache_set('apachesolr:environments', $environments, 'cache_apachesolr');
}
$conf_environments = variable_get('apachesolr_environments', array());
if (!empty($conf_environments)) {
$environments = apachesolr_array_merge_deep_array(array(
$environments,
$conf_environments,
));
}
return $environments;
}
function apachesolr_array_merge_deep_array($arrays) {
$result = array();
foreach ($arrays as $array) {
foreach ($array as $key => $value) {
if (is_integer($key)) {
$result[] = $value;
}
elseif (isset($result[$key]) && is_array($result[$key]) && is_array($value)) {
$result[$key] = apachesolr_array_merge_deep_array(array(
$result[$key],
$value,
));
}
else {
$result[$key] = $value;
}
}
}
return $result;
}
function apachesolr_environment_load($env_id, $reset = FALSE) {
if ($reset) {
apachesolr_environments_clear_cache();
}
$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) {
static $environments;
static $solr_cache;
$environment = apachesolr_environment_load($env_id);
if ($environment) {
$query = "DELETE FROM {apachesolr_environment} WHERE env_id = '%s'";
db_query($query, $env_id);
$query = "DELETE FROM {apachesolr_environment_variable} WHERE env_id = '%s'";
db_query($query, $env_id);
$query = "DELETE FROM {apachesolr_index_bundles} WHERE env_id = '%s'";
db_query($query, $env_id);
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');
if (db_result(db_query("SELECT 1 FROM {apachesolr_environment} WHERE env_id = '%s'", $environment['env_id']))) {
$query = "UPDATE {apachesolr_environment} SET name = '%s', url = '%s', service_class = '%s' WHERE env_id = '%s'";
db_query($query, array(
$environment['name'],
$environment['url'],
$environment['service_class'],
$environment['env_id'],
));
}
else {
$query = "INSERT INTO {apachesolr_environment} (env_id, name, url, service_class) VALUES ('%s', '%s', '%s', '%s')";
db_query($query, array(
$environment['env_id'],
$environment['name'],
$environment['url'],
$environment['service_class'],
));
}
$conf = isset($environment['conf']) ? $environment['conf'] : array();
$index_bundles = isset($environment['index_bundles']) ? $environment['index_bundles'] : array();
foreach ($conf as $name => $value) {
apachesolr_environment_variable_set($environment['env_id'], $name, $value);
}
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() {
apachesolr_get_solr(NULL, TRUE);
apachesolr_load_all_environments(TRUE);
}
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) {
$query = "INSERT INTO {apachesolr_environment_variable} (env_id, name, value)\n VALUES ('%s','%s','%s')\n ON DUPLICATE KEY UPDATE env_id = '%s', name = '%s', value = '%s'";
db_query($query, array(
$env_id,
$name,
serialize($value),
$env_id,
$name,
serialize($value),
));
apachesolr_environments_clear_cache();
}
function apachesolr_environment_variable_del($env_id, $name) {
$query = "DELETE FROM {apachesolr_environment_variable} WHERE env_id = '%s' AND name = '%s'";
db_query($query, array(
$env_id,
$name,
));
apachesolr_environments_clear_cache();
}
function apachesolr_server_status($url, $class = NULL, $class_info = NULL) {
static $status = array();
$class = apachesolr_load_service_class($class, $class_info);
$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) {
watchdog('Apache Solr', nl2br(check_plain($e
->getMessage())), NULL, WATCHDOG_ERROR);
}
$status[$key] = $ping;
}
return $status[$key];
}
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_';
return substr($type_prefix . $sm . $field['name'], 0, 32);
}
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(' ', $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) {
static $_response = 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 = '', $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']);
}
return new $class($operator);
}
function apachesolr_current_query($env_id, DrupalSolrQueryInterface $query = NULL) {
static $saved_query = 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_field_name_map($field_name) {
static $map;
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 (Stemmed)'),
'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. story'),
'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) {
if (is_array($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_get_index_callbacks() {
$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);
return $default_entity_info;
}
function apachesolr_content_extra_fields($content_type) {
$environments = apachesolr_load_all_environments();
$default_entity_info = apachesolr_get_index_callbacks();
if (!isset($extra['apachesolr'])) {
$extra['apachesolr'] = array();
}
$entity_type = 'node';
if (isset($default_entity_info[$entity_type])) {
$extra['apachesolr'] += $default_entity_info[$entity_type];
}
$default = array(
'indexable' => FALSE,
'status callback' => '',
'document callback' => '',
'reindex callback' => '',
'bundles changed callback' => '',
'label' => t('Apachesolr settings'),
'description' => 'Apachesolr Content type info',
'weight' => 100,
);
$extra['apachesolr'] += $default;
$extra['apachesolr']['index'] = FALSE;
foreach ($environments as $env) {
if (empty($env['env_id']['conf']['apachesolr_read_only'])) {
$supported = apachesolr_get_index_bundles($env['env_id'], $entity_type);
if (in_array($content_type, $supported)) {
$extra['apachesolr']['index'] = TRUE;
break;
}
}
}
return $extra;
}
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_should_index($entity, $type) {
$info = content_types();
$id = $entity->nid;
$bundle = $entity->type;
$env_id = apachesolr_default_environment();
$bundles = apachesolr_get_index_bundles($env_id, 'node');
if ($bundle && isset($info[$bundle]['extra']['apachesolr']['index']) && $info[$bundle]['extra']['apachesolr']['index']) {
return TRUE;
}
return FALSE;
}
function apachesolr_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'delete':
apachesolr_entity_delete($node, 'node');
break;
case 'insert':
case 'update':
apachesolr_entity_update($node, 'node');
break;
}
}
function apachesolr_entity_update($entity, $type) {
module_load_include('inc', 'apachesolr', 'apachesolr.index');
if (apachesolr_entity_should_index($entity, $type)) {
$id = $entity->nid;
$bundle = $entity->type;
$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);
}
}
}
if (!$status) {
apachesolr_entity_delete($entity, $type);
return;
}
$indexer_table = apachesolr_get_indexer_table($type);
$query = "INSERT INTO {{$indexer_table}} (entity_type, entity_id, bundle, status, changed)\n VALUES ('%s', %d, '%s', %d, %d)\n ON DUPLICATE KEY UPDATE entity_type = '%s', entity_id = %d, bundle = '%s', status = %d, changed = %d";
db_query($query, array(
$type,
$id,
$bundle,
1,
APACHESOLR_REQUEST_TIME,
$type,
$id,
$bundle,
1,
APACHESOLR_REQUEST_TIME,
));
}
}
function apachesolr_get_indexer_table($type) {
$entity_info = apachesolr_get_index_callbacks();
if (isset($entity_info[$type]['index_table'])) {
$indexer_table = $entity_info[$type]['index_table'];
}
else {
$indexer_table = 'apachesolr_index_entities';
}
return db_escape_table($indexer_table);
}
function apachesolr_entity_delete($entity, $entity_type) {
$env_id = apachesolr_default_environment();
module_load_include('inc', 'apachesolr', 'apachesolr.index');
apachesolr_remove_entity($env_id, $entity_type, $entity->nid);
}
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)) {
$query = "DELETE FROM {{$indexer_table}} WHERE entity_type = '%s' AND entity_id = %d";
db_query($query, array(
$entity_type,
$entity_id,
));
}
else {
$query = "UPDATE {{$indexer_table}} asn SET asn.changed = '%s', status = %d WHERE asn.entity_id = %d";
db_query($query, array(
APACHESOLR_REQUEST_TIME,
0,
$entity_id,
));
}
}
function apachesolr_entity_fields($entity_type = 'node') {
static $fields = array();
if (!isset($fields[$entity_type])) {
$fields[$entity_type] = array();
$mappings = apachesolr_get_field_mappings($entity_type);
if (module_exists('content')) {
foreach (content_fields() as $field_name => $field) {
$row = array();
if (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;
$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'] = $field['widget']['module'];
$result = db_query("SELECT nt.type FROM {" . content_instance_tablename() . "} nfi " . "LEFT JOIN {node_type} nt ON nt.type = nfi.type_name " . "WHERE nfi.field_name = '%s' " . "AND nfi.widget_active = 1", $field['field_name']);
while ($type = db_fetch_array($result)) {
$bundle = content_types($type['type']);
$field_display = isset($bundle['fields'][$field_name]['display_settings']) ? $bundle['fields'][$field_name]['display_settings'] : array();
if (empty($field_display[NODE_BUILD_SEARCH_INDEX]) || !$field_display[NODE_BUILD_SEARCH_INDEX]['exclude'] && $field_display[NODE_BUILD_SEARCH_INDEX]['format'] != 'hidden') {
$row['display_name'] = $bundle['fields'][$field_name]['widget']['label'];
$row['bundles'][] = $bundle['fields'][$field_name]['type_name'];
}
}
if (!empty($row['bundles'])) {
$fields[$entity_type][apachesolr_index_key($row)][] = $row;
}
}
}
}
if (module_exists('taxonomy')) {
foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
$field = $mappings['taxonomy_term'];
$field['name'] = 'taxonomy_vid_' . $vid;
$field['module_name'] = $vocabulary->module;
$field['display_name'] = $vocabulary->name;
$field['bundles'] = $vocabulary->nodes;
$field['multiple'] = true;
$field['field'] = array();
$field['field']['field_name'] = 'taxonomy';
$field['field']['vid'] = $vid;
$field['field']['type'] = 'taxonomy_term';
if (!empty($field['bundles'])) {
$fields[$entity_type][apachesolr_index_key($field)] = array(
$field,
);
}
}
}
}
return $fields[$entity_type];
}
function apachesolr_get_field_mappings($entity_type) {
static $field_mappings = 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 content_apachesolr_index_document_build(ApacheSolrDocument $document, $entity, $entity_type) {
_content_field_invoke('sanitize', $entity);
$indexed_fields = apachesolr_entity_fields($entity_type);
foreach ($indexed_fields as $index_key => $nodefields) {
if (!empty($nodefields)) {
foreach ($nodefields as $field_info) {
if (is_array($field_info['field'])) {
$field_name = $field_info['field']['field_name'];
}
if (isset($entity->{$field_name})) {
$function = $field_info['indexing_callback'];
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 = content_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]['#value'] = filter_xss($allowed_values[$key]);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#value'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#value'] = filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_nodereference_map_callback($facets, $options) {
$map = array();
$allowed_values = array();
$fields = content_fields();
$field_name = $options['field']['field_name'];
if (isset($fields[$field_name])) {
$allowed_values = _nodereference_potential_references($fields[$field_name]);
}
foreach ($facets as $key) {
if (isset($allowed_values[$key])) {
$map[$key]['#value'] = filter_xss($allowed_values[$key]['title']);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#value'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#value'] = filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_userreference_map_callback($facets, $options) {
$map = array();
$allowed_values = array();
$fields = content_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]['#value'] = filter_xss($allowed_values[$key]['title']);
}
elseif ($key === '_empty_' && !empty($options['facet missing allowed'])) {
$map[$key]['#value'] = theme('facetapi_facet_missing', array(
'field_name' => $options['display_name'],
));
}
else {
$map[$key]['#value'] = filter_xss($key);
}
$map[$key]['#html'] = TRUE;
}
return $map;
}
function apachesolr_entity_get_callback($entity_type, $callback, $bundle = NULL) {
$info = content_types();
$callback_function = NULL;
if ($bundle && isset($info[$bundle]['extra']['apachesolr'][$callback])) {
$callback_function = $info[$bundle]['extra']['apachesolr'][$callback];
}
else {
$callbacks = apachesolr_get_index_callbacks();
$callback_function = $callbacks[$entity_type][$callback];
}
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 content_apachesolr_field_mappings() {
$mappings = array(
'number_integer' => array(
'indexing_callback' => 'apachesolr_index_content_numeric_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' => 'apachesolr_index_content_numeric_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' => 'apachesolr_index_content_numeric_indexing_callback',
'index_type' => 'tfloat',
'facets' => TRUE,
'query types' => array(
'term',
'numeric_range',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
'text' => array(
'indexing_callback' => 'apachesolr_index_content_text_indexing_callback',
'index_type' => 'string',
'facets' => TRUE,
'query types' => array(
'term',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
);
return $mappings;
}
function taxonomy_apachesolr_field_mappings() {
$mappings = array(
'taxonomy_term' => array(
'map callback' => 'facetapi_map_taxonomy_terms',
'hierarchy callback' => 'facetapi_get_taxonomy_hierarchy',
'indexing_callback' => 'apachesolr_term_indexing_callback',
'index_type' => 'integer',
'facets' => TRUE,
'query types' => array(
'term',
),
'query type' => 'term',
'facet mincount allowed' => TRUE,
),
);
return $mappings;
}
function date_apachesolr_field_mappings() {
$mappings = array();
$default = array(
'indexing_callback' => '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'] = 'apachesolr_datestamp_default_indexing_callback';
return $mappings;
}
function apachesolr_get_min_date(array $facet) {
$table = 'field_data_' . $facet['field api name'];
$table = db_escape_table($table);
$column = $facet['field api name'] . '_value';
$query_min = db_result(db_query("SELECT MIN('%s') min FROM {{$table}} t", array(
$column,
)));
if (!is_int($query_min)) {
$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'];
$table = db_escape_table($table);
$column = $facet['field api name'] . '_value';
$query_max = db_result(db_query("SELECT MAX('%s') min FROM {{$table}} t", array(
$column,
)));
if (!is_int($query_max)) {
$return = strtotime($query_max);
if ($return === FALSE) {
$return = time() + 52 * 7 * 24 * 60 * 60;
}
}
return $return;
}
function nodereference_apachesolr_field_mappings() {
$mappings = array(
'nodereference' => array(
'indexing_callback' => 'apachesolr_nodereference_indexing_callback',
'index_type' => 'integer',
'map callback' => 'apachesolr_nodereference_map_callback',
'facets' => TRUE,
),
);
return $mappings;
}
function userreference_apachesolr_field_mappings() {
$mappings = array(
'userreference' => array(
'indexing_callback' => 'apachesolr_userreference_indexing_callback',
'index_type' => 'integer',
'map callback' => 'apachesolr_userreference_map_callback',
'facets' => 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', $vars['direction']);
}
if ($vars['active']) {
if (isset($vars['options']['attributes']['class'])) {
$vars['options']['attributes']['class'] .= ' active';
}
else {
$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', $vars['items']);
}
function theme_apachesolr_settings_title($vars) {
$output = '';
if ($environment = apachesolr_environment_load($vars['env_id'])) {
$url = url('admin/settings/apachesolr/settings/', array(
'query' => array(
'destination' => $_GET['q'],
),
));
$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;
}
$query = "SELECT env_id, entity_type, bundle\n FROM {apachesolr_index_bundles}\n WHERE env_id IN (" . db_placeholders($environments, 'varchar') . ")\n ORDER BY env_id, entity_type, bundle";
$all_index_bundles_results = db_query($query, array_keys($environments));
$all_index_bundles_keyed = array();
while ($all_index_bundles_result = db_fetch_array($all_index_bundles_results)) {
extract($all_index_bundles_result);
$all_index_bundles_keyed[$env_id][$entity_type][] = $bundle;
}
$query = "SELECT env_id, name, value\n FROM {apachesolr_environment_variable}\n WHERE env_id IN (" . db_placeholders($environments, 'varchar') . ")\n ORDER BY env_id, name, value";
$all_variables_results = db_query($query, array_keys($environments));
$variables = array();
while ($all_variables_result = db_fetch_array($all_variables_results)) {
extract($all_variables_result);
$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) && $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 ($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_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();
$type = 'node';
if ($bundles = apachesolr_get_index_bundles($environment->env_id, $type)) {
$index_bundles[$type] = $bundles;
}
$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);
}