View source
<?php
define('ACQUIA_SEARCH_ENVIRONMENT_ID', 'acquia_search_server_1');
if (!defined('REQUEST_TIME')) {
define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
}
function acquia_search_get_environment($conf = array()) {
if (!empty($conf['acquia_subscription_id']) && !empty($conf['acquia_subscription_key'])) {
$identifier = $conf['acquia_subscription_id'];
$key = $conf['acquia_subscription_key'];
$subscription = acquia_agent_get_subscription($params = array(), $identifier, $key);
}
else {
$identifier = acquia_agent_settings('acquia_identifier');
$subscription = acquia_agent_settings('acquia_subscription_data');
}
if (!empty($subscription['heartbeat_data']['search_service_colony'])) {
$search_base_url = 'http://' . $subscription['heartbeat_data']['search_service_colony'];
}
else {
$search_base_url = variable_get('acquia_search_base_url', 'http://search.acquia.com');
}
$environment = array(
'url' => $search_base_url . variable_get('acquia_search_path', '/solr/' . $identifier),
'service_class' => 'AcquiaSearchService',
'conf' => array(
'service_class_info' => array(
'file' => 'Acquia_Search_Service',
'module' => 'acquia_search',
'class' => 'AcquiaSearchService',
),
),
);
return $environment;
}
function acquia_search_enable() {
_acquia_search_set_version();
acquia_agent_check_subscription();
}
function acquia_search_disable() {
apachesolr_environment_delete(ACQUIA_SEARCH_ENVIRONMENT_ID);
$environments = apachesolr_load_all_environments($reset = TRUE);
foreach ($environments as $environment) {
if (acquia_search_environment_connected($environment)) {
$environment['url'] = 'http://localhost:8983/solr';
if (apachesolr_default_environment() == $environment['env_id']) {
variable_del('apachesolr_default_environment');
}
$environment['service_class'] = '';
if (is_array($environment['conf'])) {
$environment['conf']['service_class'] = '';
}
apachesolr_environment_save($environment);
}
}
variable_del('acquia_search_derived_key_salt');
}
function acquia_search_help($path, $arg) {
switch ($path) {
case 'admin/settings/apachesolr':
$env_id = $arg[4] ? $arg[4] : apachesolr_default_environment();
$environment = apachesolr_environment_load($env_id);
if (acquia_search_environment_connected($environment) && acquia_agent_subscription_is_active()) {
$as_link = l(t('Acquia Search'), 'http://www.acquia.com/products-services/acquia-search');
return t("Search is being provided by the !as network service.", array(
'!as' => $as_link,
));
}
break;
}
}
function acquia_search_enable_acquia_solr_environment() {
$environment = apachesolr_environment_load(ACQUIA_SEARCH_ENVIRONMENT_ID, $reset = TRUE);
if (!$environment) {
variable_set('apachesolr_default_environment', ACQUIA_SEARCH_ENVIRONMENT_ID);
$environment['conf'] = array();
$default_search_page_id = apachesolr_search_default_search_page();
$default_search_page = apachesolr_search_page_load($default_search_page_id);
if (!empty($default_search_page) && $default_search_page['env_id'] != ACQUIA_SEARCH_ENVIRONMENT_ID) {
$default_search_page['env_id'] = ACQUIA_SEARCH_ENVIRONMENT_ID;
apachesolr_search_page_save($default_search_page);
}
}
$acquia_environment = acquia_search_get_environment();
$environment['url'] = $acquia_environment['url'];
$environment['service_class'] = $acquia_environment['service_class'];
$environment['conf']['service_class_info'] = $acquia_environment['conf']['service_class_info'];
$environment['env_id'] = ACQUIA_SEARCH_ENVIRONMENT_ID;
$environment['name'] = t('Acquia Search');
apachesolr_environment_save($environment);
}
function acquia_search_menu_alter(&$menu) {
$delete_page = 'admin/settings/apachesolr/settings/%apachesolr_environment/delete';
if (isset($menu[$delete_page])) {
$menu[$delete_page]['access callback'] = 'acquia_search_environment_delete_access';
$menu[$delete_page]['access arguments'] = array(
4,
);
}
}
function _acquia_search_set_version() {
$version = variable_get('acquia_search_version', '6.x-3.x');
$path = drupal_get_path('module', 'acquia_search') . '/acquia_search.info';
$info = drupal_parse_info_file($path);
$new_version = isset($info['version']) ? (string) $info['version'] : '6.x-3.x';
if ($version != $new_version) {
variable_set('acquia_search_version', $new_version);
}
}
function acquia_search_environment_connected($environment) {
if ($environment['service_class'] == 'AcquiaSearchService') {
return TRUE;
}
$acquia_search_key = apachesolr_environment_variable_get($environment['env_id'], 'acquia_search_key');
if (!empty($acquia_search_key)) {
return TRUE;
}
return FALSE;
}
function acquia_search_environment_delete_access($environment) {
if ($environment['env_id'] == ACQUIA_SEARCH_ENVIRONMENT_ID && !isset($environment['export_type'])) {
return FALSE;
}
return user_access('administer search');
}
function acquia_search_form_apachesolr_settings_alter(&$form, $form_state) {
if (acquia_agent_subscription_is_active()) {
$delete_link = '<a href="/admin/settings/apachesolr/settings/' . ACQUIA_SEARCH_ENVIRONMENT_ID . '/delete">Delete</a>';
$form['apachesolr_host_settings']['table']['#value'] = str_replace($delete_link, '', $form['apachesolr_host_settings']['table']['#value']);
$form['advanced']['acquia_search_edismax_default'] = array(
'#type' => 'radios',
'#title' => t('Always allow advanced syntax for Acquia Search'),
'#default_value' => variable_get('acquia_search_edismax_default', 0),
'#options' => array(
0 => t('Disabled'),
1 => t('Enabled'),
),
'#description' => t('If enabled, all Acquia Search keyword searches may use advanced <a href="@url">Lucene syntax</a> such as wildcard searches, fuzzy searches, proximity searches, boolean operators and more via the Extended Dismax parser. If not enabled, this syntax wll only be used when needed to enable wildcard searches.', array(
'@url' => 'http://lucene.apache.org/java/2_9_3/queryparsersyntax.html',
)),
'#weight' => 10,
);
}
}
function acquia_search_form_apachesolr_environment_edit_form_alter(&$form, $form_state) {
$env_id = isset($form['env_id']['#default_value']) ? $form['env_id']['#default_value'] : '';
$environment = $env_id ? apachesolr_environment_load($env_id) : FALSE;
if ($environment && acquia_search_environment_connected($environment)) {
$form['url']['#value'] = $form['url']['#default_value'];
$form['url']['#attributes'] = array(
'readonly' => 'readonly',
);
$form['env_id']['#value'] = $form['env_id']['#default_value'];
$form['env_id']['#disabled'] = array(
'readonly' => 'readonly',
);
}
if ($env_id == ACQUIA_SEARCH_ENVIRONMENT_ID) {
$form['name']['#value'] = $form['name']['#default_value'];
$form['name']['#disabled'] = array(
'readonly' => 'readonly',
);
$form['actions']['delete']['#access'] = FALSE;
$form['actions']['cancel']['#access'] = FALSE;
}
$form['actions']['save']['#validate'][] = 'acquia_search_environment_edit_form_validate';
}
function acquia_search_environment_edit_form_validate($form, &$form_state) {
if ($form_state['values']['env_id'] == ACQUIA_SEARCH_ENVIRONMENT_ID) {
$form_state['values'] = array_merge($form_state['values'], acquia_search_get_environment());
}
}
function acquia_search_acquia_subscription_status($active, $subscription = FALSE) {
if ($active) {
acquia_search_enable_acquia_solr_environment();
$salt = variable_get('acquia_search_derived_key_salt', '');
if (isset($subscription['derived_key_salt']) && $salt != $subscription['derived_key_salt']) {
variable_set('acquia_search_derived_key_salt', $subscription['derived_key_salt']);
}
}
else {
if (is_int($subscription)) {
switch ($subscription) {
case SUBSCRIPTION_NOT_FOUND:
case SUBSCRIPTION_EXPIRED:
acquia_search_disable();
break;
}
}
}
_acquia_search_set_version();
}
function acquia_search_auth_cookie(&$url, $string = '', $derived_key = NULL, $env_id = NULL) {
$uri = parse_url($url);
if (in_array('ssl', stream_get_transports(), TRUE) && !defined('ACQUIA_DEVELOPMENT_NOSSL')) {
$scheme = 'https://';
$port = '';
}
else {
$scheme = 'http://';
$port = isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
}
$path = isset($uri['path']) ? $uri['path'] : '/';
$query = isset($uri['query']) ? '?' . $uri['query'] : '';
$url = $scheme . $uri['host'] . $port . $path . $query;
$nonce = base64_encode(acquia_search_random_bytes(24));
if ($string) {
$auth_header = acquia_search_authenticator($string, $nonce, $derived_key, $env_id);
}
else {
$auth_header = acquia_search_authenticator($path . $query, $nonce, $derived_key, $env_id);
}
return array(
$auth_header,
$nonce,
);
}
function acquia_search_derived_key_salt() {
$salt = variable_get('acquia_search_derived_key_salt', '');
if (!$salt) {
$subscription = acquia_agent_settings('acquia_subscription_data');
if (isset($subscription['derived_key_salt'])) {
variable_set('acquia_search_derived_key_salt', $subscription['derived_key_salt']);
$salt = $subscription['derived_key_salt'];
}
}
return $salt;
}
function _acquia_search_derived_key($env_id = NULL) {
static $derived_key = array();
if (empty($env_id)) {
$env_id = 0;
}
if (!isset($derived_key[$env_id])) {
$identifier = acquia_agent_settings('acquia_identifier');
$key = acquia_agent_settings('acquia_key');
if ($env_id) {
if ($search_key = apachesolr_environment_variable_get($env_id, 'acquia_search_key')) {
$derived_key[$env_id] = $search_key;
}
}
$derived_key_salt = acquia_search_derived_key_salt();
if (empty($derived_key_salt) || empty($key) || empty($identifier)) {
$derived_key[$env_id] = '';
}
elseif (!isset($derived_key[$env_id])) {
$derived_key[$env_id] = _acquia_search_create_derived_key($derived_key_salt, $identifier, $key);
}
}
return $derived_key[$env_id];
}
function _acquia_search_create_derived_key($salt, $id, $key) {
$derivation_string = $id . 'solr' . $salt;
return hash_hmac('sha1', str_pad($derivation_string, 80, $derivation_string), $key);
}
function acquia_search_authenticator($string, $nonce, $derived_key = NULL, $env_id = NULL) {
if (empty($derived_key)) {
$derived_key = _acquia_search_derived_key($env_id);
}
if (empty($derived_key)) {
return '';
}
else {
$time = REQUEST_TIME;
return 'acquia_solr_time=' . $time . '; acquia_solr_nonce=' . $nonce . '; acquia_solr_hmac=' . hash_hmac('sha1', $time . $nonce . $string, $derived_key) . ';';
}
}
function acquia_search_valid_response($hmac, $nonce, $string, $derived_key = NULL, $env_id = NULL) {
if (empty($derived_key)) {
$derived_key = _acquia_search_derived_key($env_id);
}
return $hmac == hash_hmac('sha1', $nonce . $string, $derived_key);
}
function acquia_search_extract_hmac($headers) {
$reg = array();
if (is_array($headers)) {
foreach ($headers as $name => $value) {
if (strtolower($name) == 'pragma' && preg_match("/hmac_digest=([^;]+);/i", $value, $reg)) {
return trim($reg[1]);
}
}
}
return '';
}
function acquia_search_apachesolr_query_alter($query) {
$environment = apachesolr_environment_load($query
->solr('getId'));
if (!acquia_search_environment_connected($environment) || $query
->getParam('qt') || $query
->getParam('defType')) {
return;
}
$keys = $query
->getParam('q');
if ($keys && (($wildcard = preg_match('/\\S+[*?]/', $keys)) || variable_get('acquia_search_edismax_default', 0))) {
$query
->addParam('defType', 'edismax');
if ($wildcard) {
$keys = preg_replace_callback('/(\\S+[*?]\\S*)/', '_acquia_search_lower', $keys);
$query
->replaceParam('q', $keys);
}
}
}
function _acquia_search_lower($matches) {
return drupal_strtolower($matches[1]);
}
function acquia_search_random_bytes($count) {
static $random_state, $bytes, $php_compatible;
if (!isset($random_state)) {
$random_state = print_r($_SERVER, TRUE);
if (function_exists('getmypid')) {
$random_state .= getmypid();
}
$bytes = '';
}
if (strlen($bytes) < $count) {
if (!isset($php_compatible)) {
$php_compatible = version_compare(PHP_VERSION, '5.3.4', '>=');
}
if ($fh = @fopen('/dev/urandom', 'rb')) {
$bytes .= fread($fh, max(4096, $count));
fclose($fh);
}
elseif ($php_compatible && function_exists('openssl_random_pseudo_bytes')) {
$bytes .= openssl_random_pseudo_bytes($count - strlen($bytes));
}
while (strlen($bytes) < $count) {
$random_state = hash('sha256', microtime() . mt_rand() . $random_state);
$bytes .= hash('sha256', mt_rand() . $random_state, TRUE);
}
}
$output = substr($bytes, 0, $count);
$bytes = substr($bytes, $count);
return $output;
}