Mercurial > hg > MPIWG-drupal-modules
view sites/all/modules/custom/solrsearch/solrsearch.admin.inc @ 0:015d06b10d37 default tip
initial
author | dwinter |
---|---|
date | Wed, 31 Jul 2013 13:49:13 +0200 |
parents | |
children |
line wrap: on
line source
<?php /** * @file * Administrative pages for the Apache Solr framework. */ /** * Form to delete a search environment * * @param array $form * @param array $form_state * @param array $environment * * @return array output of confirm_form() */ function solrsearch_environment_delete_form(array $form, array &$form_state, array $environment) { $form['env_id'] = array( '#type' => 'value', '#value' => $environment['env_id'], ); if (isset($environment['export_type']) && $environment['export_type'] == 3) { $verb = t('Revert'); } else { $verb = t('Delete'); } return confirm_form( $form, t('Are you sure you want to !verb search environment %name?', array('%name' => $environment['name'], '!verb' => strtolower($verb))), 'admin/config/search/solrsearch', t('This action cannot be undone.'), $verb, t('Cancel') ); } /** * Submit handler for the delete form * * @param array $form * @param array $form_state */ function solrsearch_environment_delete_form_submit(array $form, array &$form_state) { if (solrsearch_environment_delete($form_state['values']['env_id'])) { drupal_set_message(t('The search environment was deleted')); } $form_state['redirect'] = 'admin/config/search/solrsearch/settings'; } function solrsearch_environment_edit_delete_submit($form, &$form_state) { $form_state['redirect'] = 'admin/config/search/solrsearch/settings/' . $form_state['values']['env_id'] . '/delete'; // Regardlessly of the destination parameter we want to go to another page unset($_GET['destination']); drupal_static_reset('drupal_get_destination'); drupal_get_destination(); } /** * Settings page for a specific environment (or default one if not provided) * * @param array|bool $environment * * @return array Render array for a settings page */ function solrsearch_environment_settings_page(array $environment = array()) { if (empty($environment)) { $env_id = solrsearch_default_environment(); $environment = solrsearch_environment_load($env_id); } $env_id = $environment['env_id']; // Initializes output with information about which environment's setting we are // editing, as it is otherwise not transparent to the end user. $output = array( 'solrsearch_environment' => array( '#theme' => 'solrsearch_settings_title', '#env_id' => $env_id, ), ); $output['form'] = drupal_get_form('solrsearch_environment_edit_form', $environment); return $output; } /** * Form to clone a certain environment * * @param array $form * @param array $form_state * @param array $environment * * @return array output of confirm_form() */ function solrsearch_environment_clone_form(array $form, array &$form_state, array $environment) { $form['env_id'] = array( '#type' => 'value', '#value' => $environment['env_id'], ); return confirm_form( $form, t('Are you sure you want to clone search environment %name?', array('%name' => $environment['name'])), 'admin/config/search/solrsearch', '', t('Clone'), t('Cancel') ); } /** * Submit handler for the clone form * * @param array $form * @param array $form_state */ function solrsearch_environment_clone_form_submit(array $form, array &$form_state) { if (solrsearch_environment_clone($form_state['values']['env_id'])) { drupal_set_message(t('The search environment was cloned')); } $form_state['redirect'] = 'admin/config/search/solrsearch/settings'; } /** * Submit handler for the confirmation page of cloning an environment * * @param array $form * @param array $form_state */ function solrsearch_environment_clone_submit(array $form, array &$form_state) { $form_state['redirect'] = 'admin/config/search/solrsearch/settings/' . $form_state['values']['env_id'] . '/clone'; } /** * Form builder for adding/editing a Solr environment used as a menu callback. */ function solrsearch_environment_edit_form(array $form, array &$form_state, array $environment = array()) { if (empty($environment)) { $environment = array(); } $environment += array('env_id' => '', 'name' => '', 'url' => '', 'service_class' => '', 'conf' => array()); $form['#environment'] = $environment; $form['url'] = array( '#type' => 'textfield', '#title' => t('Solr server URL'), '#default_value' => $environment['url'], '#description' => t('Example: http://localhost:8983/solr'), '#required' => TRUE, ); $is_default = $environment['env_id'] == solrsearch_default_environment(); $form['make_default'] = array( '#type' => 'checkbox', '#title' => t('Make this Solr search environment the default'), '#default_value' => $is_default, '#disabled' => $is_default, ); $form['name'] = array( '#type' => 'textfield', '#title' => t('Description'), '#default_value' => $environment['name'], '#required' => TRUE, ); $form['env_id'] = array( '#type' => 'machine_name', '#title' => t('Environment id'), '#machine_name' => array( 'exists' => 'solrsearch_environment_load', ), '#default_value' => $environment['env_id'], '#disabled' => !empty($environment['env_id']), // Cannot change it once set. '#description' => t('Unique, machine-readable identifier for this Solr environment.'), '#required' => TRUE, ); $form['service_class'] = array( '#type' => 'value', '#value' => $environment['service_class'], ); $form['conf'] = array( '#tree' => TRUE, ); $form['conf']['solrsearch_read_only'] = array( '#type' => 'radios', '#title' => t('Index write access'), '#default_value' => isset($environment['conf']['solrsearch_read_only']) ? $environment['conf']['solrsearch_read_only'] : solrsearch_READ_WRITE, '#options' => array(solrsearch_READ_WRITE => t('Read and write (normal)'), solrsearch_READ_ONLY => t('Read only')), '#description' => t('<em>Read only</em> stops this site from sending updates to this search environment. Useful for development sites.'), ); $form['actions'] = array( '#type' => 'actions', ); $form['actions']['save'] = array( '#type' => 'submit', '#validate' => array('solrsearch_environment_edit_validate'), '#submit' => array('solrsearch_environment_edit_submit'), '#value' => t('Save'), ); $form['actions']['save_edit'] = array( '#type' => 'submit', '#validate' => array('solrsearch_environment_edit_validate'), '#submit' => array('solrsearch_environment_edit_submit'), '#value' => t('Save and edit'), ); $form['actions']['test'] = array( '#type' => 'submit', '#validate' => array('solrsearch_environment_edit_validate'), '#submit' => array('solrsearch_environment_edit_test_submit'), '#value' => t('Test connection'), ); if (!empty($environment['env_id']) && !$is_default) { $form['actions']['delete'] = array( '#type' => 'submit', '#submit' => array('solrsearch_environment_edit_delete_submit'), '#value' => t('Delete'), ); } // Ensures destination is an internal URL, builds "cancel" link. if (isset($_GET['destination']) && !url_is_external($_GET['destination'])) { $destination = $_GET['destination']; } else { $destination = 'admin/config/search/solrsearch/settings'; } $form['actions']['cancel'] = array( '#type' => 'link', '#title' => t('Cancel'), '#href' => $destination, ); return $form; } /** * Submit handler for the test button in the environment edit page * * @param array $form * @param array $form_state */ function solrsearch_environment_edit_test_submit(array $form, array &$form_state) { $ping = solrsearch_server_status($form_state['values']['url'], $form_state['values']['service_class']); if ($ping) { drupal_set_message(t('Your site has contacted the Apache Solr server.')); } else { drupal_set_message(t('Your site was unable to contact the Apache Solr server.'), 'error'); } $form_state['rebuild'] = TRUE; } /** * Validate handler for the environment edit page * * @param array $form * @param array $form_state */ function solrsearch_environment_edit_validate(array $form, array &$form_state) { $parts = parse_url($form_state['values']['url']); foreach (array('scheme', 'host', 'path') as $key) { if (empty($parts[$key])) { form_set_error('url', t('The Solr server URL needs to include a !part', array('!part' => $key))); } } if (isset($parts['port'])) { // parse_url() should always give an integer for port. Since drupal_http_request() // also uses parse_url(), we don't need to validate anything except the range. $pattern = empty($parts['user']) ? '@://[^:]+:([^/]+)@' : '#://[^@]+@[^:]+:([^/]+)#'; preg_match($pattern, $form_state['values']['url'], $m); if (empty($m[1]) || !ctype_digit($m[1]) || $m[1] < 1 || $m[1] > 65535) { form_set_error('port', t('The port has to be an integer between 1 and 65535.')); } else { // Normalize the url by removing extra slashes and whitespace. $form_state['values']['url'] = trim($form_state['values']['url'], "/ \t\r\n\0\x0B"); } } } /** * Submit handler for the environment edit page * * @param array $form * @param array $form_state */ function solrsearch_environment_edit_submit(array $form, array &$form_state) { solrsearch_environment_save($form_state['values']); if (!empty($form_state['values']['make_default'])) { solrsearch_set_default_environment($form_state['values']['env_id']); } cache_clear_all('solrsearch:environments', 'cache_solrsearch'); drupal_set_message(t('The %name search environment has been saved.', array('%name' => $form_state['values']['name']))); if ($form_state['values']['op'] == t('Save')) { $form_state['redirect'] = 'admin/config/search/solrsearch/settings'; } else { $form_state['redirect'] = current_path(); } // Regardlessly of the destination parameter we want to go to another page unset($_GET['destination']); drupal_static_reset('drupal_get_destination'); drupal_get_destination(); } /** * Check to see if the facetapi module is installed, and if not put up * a message. * * Only call this function if the user is already in a position for this to * be useful. */ function solrsearch_check_facetapi() { if (!module_exists('facetapi')) { $filename = db_query_range("SELECT filename FROM {system} WHERE type = 'module' AND name = 'facetapi'", 0, 1) ->fetchField(); if ($filename && file_exists($filename)) { drupal_set_message(t('If you <a href="@modules">enable the facetapi module</a>, Apache Solr Search will provide you with configurable facets.', array('@modules' => url('admin/modules')))); } else { drupal_set_message(t('If you install the facetapi module from !href, Apache Solr Search will provide you with configurable facets.', array('!href' => url('http://drupal.org/project/facetapi')))); } } } /** * Form builder for general settings used as a menu callback. * * @param array $form * @param array $form_state * * @return array Output of the system_settings_form() */ function solrsearch_settings(array $form, array &$form_state) { $form = array(); $rows = array(); // Environment settings // Take environment settings form solrsearch $id = solrsearch_default_environment(); $environments = solrsearch_load_all_environments(); $default_environment = solrsearch_default_environment(); solrsearch_check_facetapi(); // Reserve a row for the default one $rows[$default_environment] = array(); foreach ($environments as $environment_id => $data) { // Define all the Operations $confs = array(); $ops = array(); // Whenever facetapi is enabled we also enable our operation link if (module_exists('facetapi')) { $confs['facets'] = array( 'class' => 'operation', 'data' => l(t('Facets'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/facets', array('query' => array('destination' => current_path())) ), ); } // These are our result and bias settings if (module_exists('solrsearch_search')) { $confs['result_bias'] = array( 'class' => 'operation', 'data' => l(t('Bias'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/bias', array('query' => array('destination' => current_path())) ), ); } $ops['edit'] = array( 'class' => 'operation', 'data' => l(t('Edit'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/edit', array('query' => array('destination' => current_path())) ), ); $ops['clone'] = array( 'class' => 'operation', 'data' => l(t('Clone'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/clone', array('query' => array('destination' => $_GET['q'])) ), ); $env_name = l($data['name'], 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/edit', array('query' => array('destination' => $_GET['q']))); // Is this row our default environment? if ($environment_id == $default_environment) { $env_name = t('!environment <em>(Default)</em>', array('!environment' => $env_name)); $env_class_row = 'default-environment'; } else { $env_class_row = ''; } // For every non-default we add a delete link // Allow to revert a search environment or to delete it $delete_value = ''; if (!isset($data['in_code_only'])) { if ((isset($data['type']) && $data['type'] == 'Overridden')) { $delete_value = array( 'class' => 'operation', 'data' => l(t('Revert'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/delete'), ); } // don't allow the deletion of the default environment elseif ($environment_id != $default_environment) { $delete_value = array( 'class' => 'operation', 'data' => l(t('Delete'), 'admin/config/search/solrsearch/settings/' . $data['env_id'] . '/delete'), ); } } $ops['delete'] = $delete_value; // When we are receiving a http POST (so the page does not show) we do not // want to check the statusses of any environment $class = ''; if (empty($form_state['input'])) { $class = solrsearch_server_status($data['url'], $data['service_class']) ? 'ok' : 'error'; } $headers = array( array('data' => t('Name'), 'colspan' => 2), t('URL'), array('data' => t('Configuration'), 'colspan' => count($confs)), array('data' => t('Operations'), 'colspan' => count($ops)), ); $rows[$environment_id] = array('data' => array( // Cells array( 'class' => 'status-icon', 'data' => '<div title="' . $class . '"><span class="element-invisible">' . $class . '</span></div>', ), array( 'class' => $env_class_row, 'data' => $env_name, ), check_plain($data['url']), ), 'class' => array(drupal_html_class($class)), ); // Add the links to the page $rows[$environment_id]['data'] = array_merge($rows[$environment_id]['data'], $confs); $rows[$environment_id]['data'] = array_merge($rows[$environment_id]['data'], $ops); } $form['solrsearch_host_settings']['actions'] = array( '#markup' => '<ul class="action-links">' . drupal_render($actions) . '</ul>', ); $form['solrsearch_host_settings']['table'] = array( '#theme' => 'table', '#header' => $headers, '#rows' => array_values($rows), '#attributes' => array('class' => array('admin-solrsearch')), ); $form['advanced'] = array( '#type' => 'fieldset', '#title' => t('Advanced configuration'), '#collapsed' => TRUE, '#collapsible' => TRUE, ); $form['advanced']['solrsearch_set_nodeapi_messages'] = array( '#type' => 'radios', '#title' => t('Extra help messages for administrators'), '#description' => t('Adds notices to a page whenever Drupal changed content that needs reindexing'), '#default_value' => variable_get('solrsearch_set_nodeapi_messages', 1), '#options' => array(0 => t('Disabled'), 1 => t('Enabled')), ); // Number of Items to index $numbers = drupal_map_assoc(array(1, 5, 10, 20, 50, 100, 200)); $default_cron_limit = variable_get('solrsearch_cron_limit', 50); // solrsearch_cron_limit may be overridden in settings.php. If its current // value is not among the default set of options, add it. if (!isset($numbers[$default_cron_limit])) { $numbers[$default_cron_limit] = $default_cron_limit; } $form['advanced']['solrsearch_cron_limit'] = array( '#type' => 'select', '#title' => t('Number of items to index per cron run'), '#default_value' => $default_cron_limit, '#options' => $numbers, '#description' => t('Reduce the number of items to prevent timeouts and memory errors while indexing.', array('@cron' => url('admin/reports/status'))) ); $options = array('solrsearch:show_error' => t('Show error message')); $system_info = system_get_info('module'); if (module_exists('search')) { foreach (search_get_info() as $module => $search_info) { // Don't allow solrsearch to return results on failure of solrsearch. if ($module == 'solrsearch_search') { continue; } $options[$module] = t('Show @name search results', array('@name' => $system_info[$module]['name'])); } } $options['solrsearch:show_no_results'] = t('Show no results'); $form['advanced']['solrsearch_failure'] = array( '#type' => 'select', '#title' => t('On failure'), '#options' => $options, '#default_value' => variable_get('solrsearch_failure', 'solrsearch:show_error'), ); return system_settings_form($form); } /** * Gets information about the fields already in solr index. * * @param array $environment * The environment for which we need to ask the status from * * @return array page render array */ function solrsearch_status_page($environment = array()) { if (empty($environment)) { $env_id = solrsearch_default_environment(); $environment = solrsearch_environment_load($env_id); } else { $env_id = $environment['env_id']; } // Check for availability if (!solrsearch_server_status($environment['url'], $environment['service_class'])) { drupal_set_message(t('The server seems to be unavailable. Please verify the server settings at the <a href="!settings_page">settings page</a>', array('!settings_page' => url("admin/config/search/solrsearch/settings/{$environment['env_id']}/edit", array('query' => drupal_get_destination())))), 'warning'); return ''; } try { $solr = solrsearch_get_solr($environment["env_id"]); $solr->clearCache(); $data = $solr->getLuke(); } catch (Exception $e) { watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); drupal_set_message(nl2br(check_plain($e->getMessage())), "warning"); $data = new stdClass; $data->fields = array(); } $messages = array(); // Initializes output with information about which server's setting we are // editing, as it is otherwise not transparent to the end user. $output['solrsearch_index_action_status'] = array( '#prefix' => '<h3>' . t('@environment: Search Index Content', array('@environment' => $environment['name'])) . '</h3>', '#theme' => 'table', '#header' => array(t('Type'), t('Value')), '#rows' => $messages, ); $output['viewmore'] = array( '#markup' => l(t('View more details on the search index contents'), 'admin/reports/solrsearch'), ); $write_status = solrsearch_environment_variable_get($env_id, 'solrsearch_read_only', solrsearch_READ_WRITE); if ($write_status == solrsearch_READ_WRITE) { /*$output['index_action_form'] = drupal_get_form('solrsearch_index_action_form', $env_id); $output['index_config_form'] = drupal_get_form('solrsearch_index_config_form', $env_id);*/ } else { drupal_set_message(t('Options for deleting and re-indexing are not available because the index is read-only. This can be changed on the <a href="!settings_page">settings page</a>', array('!settings_page' => url('admin/config/search/solrsearch/settings/' . $env_id . '/edit', array('query' => drupal_get_destination())))), 'warning'); } return $output; } /** * Get the report, eg.: some statistics and useful data from the Apache Solr index * * @param array $environment * * @return array page render array */ function solrsearch_index_report(array $environment = array()) { if (empty($environment)) { $env_id = solrsearch_default_environment(); drupal_goto('admin/reports/solrsearch/' . $env_id); } $environments = solrsearch_load_all_environments(); $environments_list = array(); foreach ($environments as $env) { $var_status = array('!name' =>$env['name']); $environments_list[] = l(t('Statistics for !name', $var_status), 'admin/reports/solrsearch/' . $env['env_id']); } $output['environments_list'] = array( '#theme' => 'item_list', '#items' => $environments_list, ); try { $solr = solrsearch_get_solr($environment['env_id']); $solr->clearCache(); $data = $solr->getLuke(); } catch (Exception $e) { watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); drupal_set_message(nl2br(check_plain($e->getMessage())), "warning"); return $output; } $messages = array(); $messages[] = array(t('Number of documents in index'), $data->index->numDocs); $limit = variable_get('solrsearch_luke_limit', 20000); if (isset($data->index->numDocs) && $data->index->numDocs > $limit) { $messages[] = array(t('Limit'), t('You have more than @limit documents, so term frequencies are being omitted for performance reasons.', array('@limit' => $limit))); $not_found = t('<em>Omitted</em>'); } elseif (isset($data->index->numDocs)) { $not_found = t('Not indexed'); try { $solr = solrsearch_get_solr($environment['env_id']); // Note: we use 2 since 1 fails on Ubuntu Hardy. $data = $solr->getLuke(2); if (isset($data->index->numTerms)) { $messages[] = array(t('# of terms in index'), $data->index->numTerms); } } catch (Exception $e) { watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); $data->fields = array(); } } // Initializes output with information about which server's setting we are // editing, as it is otherwise not transparent to the end user. $fields = (array)$data->fields; if ($fields) { $messages[] = array(t('# of fields in index'), count($fields)); } // Output the messages we have for this page $output['solrsearch_index_report'] = array( '#theme' => 'table', '#header' => array('type', 'value'), '#rows' => $messages, ); if ($fields) { // Initializes table header. $header = array( 'name' => t('Field name'), 'type' => t('Index type'), 'terms' => t('Distinct terms'), ); // Builds table rows. $rows = array(); foreach ($fields as $name => $field) { // TODO: try to map the name to something more meaningful. $rows[$name] = array( 'name' => $name, 'type' => $field->type, 'terms' => isset($field->distinct) ? $field->distinct : $not_found ); } ksort($rows); // Output the fields we found for this environment $output['field_table'] = array( '#theme' => 'table', '#header' => $header, '#rows' => $rows, ); } else { $output['field_table'] = array('#markup' => t('No data on indexed fields.')); } return $output; } /** * Page callback to show available conf files. * * @param array $environment * * @return string * A non-render array but plain theme output for the config files overview. Could be done better probably */ function solrsearch_config_files_overview(array $environment = array()) { if (empty($environment)) { $env_id = solrsearch_default_environment(); } else { $env_id = $environment['env_id']; } $xml = NULL; try { $solr = solrsearch_get_solr($env_id); $response = $solr->makeServletRequest('admin/file', array('wt' => 'xml')); $xml = simplexml_load_string($response->data); } catch (Exception $e) { watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); drupal_set_message(nl2br(check_plain($e->getMessage())), "warning"); } if ($xml) { // Retrieve our items from the xml using xpath $items = $xml->xpath('//lst[@name="files"]/lst'); // Add all the data of the file in a files array $files = array(); foreach ($items as $item_id => $item) { // Do not list directories. Always a bool if (isset($item->bool)) { break; } // Get data from the files. $name = $item->attributes(); $name = ((string)$item->attributes()) ? (string)$item->attributes() : t('No name found'); $files[$item_id]['name'] = l($name, 'admin/reports/solrsearch/' . $env_id . '/conf/' . $name); // Retrieve the date attribute if (isset($item->date)) { $modified = ((string)$item->date->attributes() == 'modified') ? (string) $item->date : t('No date found'); $files[$item_id]['modified'] = format_date(strtotime($modified)); } // Retrieve the size attribute if (isset($item->long)) { $size = ((string)$item->long->attributes() == 'size') ? (string) $item->long : t('No size found'); $files[$item_id]['size'] = t('Size (bytes): @bytes', array('@bytes' => $size)); } } // Sort our files alphabetically ksort($files); // Initializes table header. $header = array( 'name' => t('File name'), 'date' => t('Modified'), 'size' => t('Size'), ); // Display the table of field names, index types, and term counts. $variables = array( 'header' => $header, 'rows' => $files, ); $output = theme('table', $variables); } else { $output = '<p>' . t('No data about any file found.') . "</p>\n"; } return $output; } /** * Page callback to show one conf file. * * @param string $name * @param array $environment * * @return string * the requested config file */ function solrsearch_config_file($name, array $environment = array()) { if (empty($environment)) { $env_id = solrsearch_default_environment(); } else { $env_id = $environment['env_id']; } $output = ''; try { $solr = solrsearch_get_solr($env_id); $response = $solr->makeServletRequest('admin/file', array('file' => $name)); $raw_file = $response->data; $output = '<pre>' . check_plain($raw_file) . '</pre>'; drupal_set_title(check_plain($name)); } catch (Exception $e) { watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); drupal_set_message(nl2br(check_plain($e->getMessage())), "warning"); } return $output; } /** * Page callback for node/%node/devel/solrsearch. * * @param object $node * @return string debugging information */ function solrsearch_devel($node) { module_load_include('inc', 'solrsearch', 'solrsearch.index'); $item = new stdClass(); $item->entity_type = 'node'; $item->entity_id = $node->nid; $output = ''; foreach (solrsearch_load_all_environments() as $env_id => $environment) { $documents = solrsearch_index_entity_to_documents($item, $env_id); $output .= '<h1>' . t('Environment %name (%env_id)', array('%name' => $environment['name'], '%env_id' => $env_id)). '</h1>'; foreach ($documents as $document) { $debug_data = array(); foreach ($document as $key => $value) { $debug_data[$key] = $value; } $output .= kdevel_print_object($debug_data); } } return $output; }