diff --git a/google_appliance.admin.inc b/google_appliance.admin.inc index 6a70861..e3ab807 100644 --- a/google_appliance.admin.inc +++ b/google_appliance.admin.inc @@ -25,28 +25,28 @@ function google_appliance_admin_settings($form) { '#collapsible' => TRUE, '#collapsed' => FALSE ); - $form['connection_info']['hostname'] = array( + $form['connection_info']['google_appliance_hostname'] = array( '#type' => 'textfield', '#title' => t('Google Search Appliance Host Name'), '#description' => t('Valid URL or IP address of the GSA device, including http:// or https://. Do not include /search at the end, or a trailing slash, but you should include a port number if needed. Example: http://my.gsabox.com:8443'), '#default_value' => $settings['hostname'], '#required' => TRUE, ); - $form['connection_info']['collection'] = array( + $form['connection_info']['google_appliance_collection'] = array( '#type' => 'textfield', '#title' => t('Collection'), '#description' => t('The name of a valid collection on the GSA device (case sensitive).'), '#default_value' => $settings['collection'], '#required' => TRUE, ); - $form['connection_info']['frontend'] = array( + $form['connection_info']['google_appliance_frontend'] = array( '#type' => 'textfield', '#title' => t('Frontend client'), '#description' => t('The name of a valid frontend client on the GSA device (case sensitive).'), '#default_value' => $settings['frontend'], '#required' => TRUE, ); - $form['connection_info']['timeout'] = array( + $form['connection_info']['google_appliance_timeout'] = array( '#type' => 'textfield', '#title' => t('Search Timeout'), '#description' => t('Length of time to wait for response from the GSA device before giving up (timeout in seconds).'), @@ -61,7 +61,7 @@ function google_appliance_admin_settings($form) { "#collapsible" => TRUE, "#collapsed" => FALSE, ); - $form['query_param']['autofilter'] = array( + $form['query_param']['google_appliance_autofilter'] = array( '#type' => 'select', '#title' => t('Search Results Auto-Filtering Options'), '#default_value' => $settings['autofilter'], @@ -95,7 +95,7 @@ function google_appliance_admin_settings($form) { '#description' => t('If there are no results in the specified language, the search appliance is expected to return results in all languages.'), ); } - $form['query_param']['query_inspection'] = array( + $form['query_param']['google_appliance_query_inspection'] = array( '#type' => 'checkbox', '#title' => t('Enable Query Inspection'), '#description' => t('Inspect the search query parameters sent to the GSA device in the Drupal message area every time a search is performed. Only really useful for sites not using the Devel module, as dsm() provides more information. The inspector is only shown to administrators, but should be disabled in a production environment.'), @@ -109,7 +109,7 @@ function google_appliance_admin_settings($form) { '#collapsible' => TRUE, '#collapsed' => FALSE ); - $form['display_settings']['drupal_path'] = array( + $form['display_settings']['google_appliance_drupal_path'] = array( '#title' => t('Search path'), '#type' => 'textfield', '#field_prefix' => '' . url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='), @@ -118,26 +118,26 @@ function google_appliance_admin_settings($form) { '#description' => t('The URL of the search page provided by this module. Include neither leading nor trailing slash.'), '#required' => TRUE, ); - $form['display_settings']['search_title'] = array( + $form['display_settings']['google_appliance_search_title'] = array( '#title' => t('Search Name'), '#type' => 'textfield', '#default_value' => $settings['search_title'], '#description' => t('Serves as the page title on results pages and the default menu item title'), '#required' => TRUE, ); - $form['display_settings']['results_per_page'] = array( + $form['display_settings']['google_appliance_results_per_page'] = array( '#title' => t('Results per page'), '#type' => 'textfield', '#default_value' => $settings['results_per_page'], '#description' => t('Number of results to show on the results page. More results will be available via a Drupal pager.'), '#required' => TRUE, ); - $form['display_settings']['spelling_suggestions'] = array( + $form['display_settings']['google_appliance_spelling_suggestions'] = array( '#type' => 'checkbox', '#title' => t('Display Spelling Suggestions'), '#default_value' => $settings['spelling_suggestions'], ); - $form['display_settings']['advanced_search_reporting'] = array( + $form['display_settings']['google_appliance_advanced_search_reporting'] = array( '#type' => 'checkbox', '#title' => t('Enable Advanced Search Reporting'), '#default_value' => $settings['advanced_search_reporting'], @@ -149,7 +149,7 @@ function google_appliance_admin_settings($form) { '#description' => t('A list of Onebox modules, one per line. Each module listed will have a corresponding block. These blocks must be placed via the block configuration page, or another layout mechanism like Context or Panels.'), '#default_value' => implode("\n", $settings['onebox_modules']), ); - $form['display_settings']['error_gsa_no_results'] = array( + $form['display_settings']['google_appliance_error_gsa_no_results'] = array( '#title' => t('No results error message'), '#type' => 'text_format', '#default_value' => $settings['error_gsa_no_results'], @@ -157,7 +157,7 @@ function google_appliance_admin_settings($form) { '#description' => t('The message displayed to the user when no results are found for the given search query.'), '#required' => TRUE, ); - $form['display_settings']['error_curl_error'] = array( + $form['display_settings']['google_appliance_error_curl_error'] = array( '#title' => t('Connection error message'), '#type' => 'text_format', '#default_value' => $settings['error_curl_error'], @@ -165,7 +165,7 @@ function google_appliance_admin_settings($form) { '#description' => t('The message displayed to the user when there is an error connecting to the search appliance.'), '#required' => TRUE, ); - $form['display_settings']['error_lib_xml_parse_error'] = array( + $form['display_settings']['google_appliance_error_lib_xml_parse_error'] = array( '#title' => t('XML parse error message'), '#type' => 'text_format', '#default_value' => $settings['error_lib_xml_parse_error'], @@ -185,7 +185,7 @@ function google_appliance_admin_settings($form) { function google_appliance_admin_settings_validate($form, &$form_state) { // host name should be a valid-format URL or IPv4 address including 'http(s)://' - if ( filter_var($form_state['values']['hostname'], FILTER_VALIDATE_URL) === FALSE) { + if ( filter_var($form_state['values']['google_appliance_hostname'], FILTER_VALIDATE_URL) === FALSE) { form_set_error( 'hostname', t('GSA Host name must be a valid-format URL or IPv4 address, including http(s)://. Example: http://my.googlebox.net.') @@ -197,7 +197,7 @@ function google_appliance_admin_settings_validate($form, &$form_state) { 'max_range' => 30, 'min_range' => 3, )); - if ( filter_var($form_state['values']['timeout'], FILTER_VALIDATE_INT, $timeout_validate_options) === FALSE ) { + if ( filter_var($form_state['values']['google_appliance_timeout'], FILTER_VALIDATE_INT, $timeout_validate_options) === FALSE ) { form_set_error( 'timeout', t('Search Timeout should be an integer from @min - @max, indicating the number of seconds to wait before the search request times out.', array( @@ -208,15 +208,15 @@ function google_appliance_admin_settings_validate($form, &$form_state) { } // Trim slashes and whitespace from drupal_path to save headaches. - $drupal_path = trim($form_state['values']['drupal_path'], ' /'); - form_set_value($form['display_settings']['drupal_path'], $drupal_path, $form_state); + $drupal_path = trim($form_state['values']['google_appliance_drupal_path'], ' /'); + form_set_value($form['display_settings']['google_appliance_drupal_path'], $drupal_path, $form_state); // results per page must be on a range that will be accepted by the device upon querying $results_per_page_validate_options = array('options' => array( 'max_range' => 1000, 'min_range' => 1 )); - if ( filter_var($form_state['values']['results_per_page'], FILTER_VALIDATE_INT, $results_per_page_validate_options) === FALSE ) { + if ( filter_var($form_state['values']['google_appliance_results_per_page'], FILTER_VALIDATE_INT, $results_per_page_validate_options) === FALSE ) { form_set_error( 'results_per_page', t('Results per page should be an integer from @min - @max.', array( @@ -228,15 +228,20 @@ function google_appliance_admin_settings_validate($form, &$form_state) { // For security, we check that the user has access to use these filters. $field_text_format_keys = array( - 'error_gsa_no_results', - 'error_curl_error', - 'error_lib_xml_parse_error', + 'google_appliance_error_gsa_no_results', + 'google_appliance_error_curl_error', + 'google_appliance_error_lib_xml_parse_error', ); $formats = filter_formats(); foreach ($field_text_format_keys as $field) { if (!filter_access($formats[$form_state['values'][$field]['format']])) { form_set_error($field . '][format', t('An illegal choice has been detected. Please contact the site administrator.')); } + else { + // Alter the formatted text area settings to our expectations. + $form_state['values'][$field . '_format'] = $form_state['values'][$field]['format']; + $form_state['values'][$field] = trim($form_state['values'][$field]['value']); + } } } @@ -245,41 +250,6 @@ function google_appliance_admin_settings_validate($form, &$form_state) { * submit handler for admin settings */ function google_appliance_admin_settings_submit($form, &$form_state) { - - $field_keys = array( - 'hostname', - 'collection', - 'frontend', - 'timeout', - 'autofilter', - 'query_inspection', - 'search_title', - 'spelling_suggestions', - 'results_per_page', - 'drupal_path', - 'advanced_search_reporting', - ); - - // save settings - foreach ($field_keys as $field) { - variable_set('google_appliance_' . $field, trim($form_state['values'][$field])); - } - - $field_text_format_keys = array( - 'error_gsa_no_results', - 'error_curl_error', - 'error_lib_xml_parse_error', - ); - - // save formatted text area settings - foreach ($field_text_format_keys as $field) { - variable_set('google_appliance_' . $field, trim($form_state['values'][$field]['value'])); - variable_set('google_appliance_' . $field . '_format', $form_state['values'][$field]['format']); - } - - // refresh settings getter - $settings = _google_appliance_get_settings(TRUE); - // make the 'search_title' and 'drupal_path' settings take effect right away menu_rebuild(); } diff --git a/google_appliance.helpers.inc b/google_appliance.helpers.inc index 0a374a4..6c51fde 100644 --- a/google_appliance.helpers.inc +++ b/google_appliance.helpers.inc @@ -15,6 +15,7 @@ define('SGA_DEFAULT_FRONTEND', 'default_frontend'); define('SGA_DEFAULT_TIMEOUT', 10); define('SGA_DEFAULT_AUTOFILTER', 1); define('SGA_DEFAULT_LANGUAGE_FILTER_TOGGLE', FALSE); +define('SGA_DEFAULT_LANGUAGE_FILTER_OPTIONS', ''); define('SGA_DEFAULT_QUERY_INSPECTION', 0); define('SGA_DEFAULT_SEARCH_TITLE', 'Search this site'); define('SGA_DEFAULT_RESULTS_PER_PAGE', 10); @@ -31,21 +32,12 @@ define('SGA_DEFAULT_ERROR_LIB_XML_PARSE_ERROR', '

The response from the search define('SGA_DEFAULT_ERROR_LIB_XML_PARSE_ERROR_FORMAT', NULL); /** - * Minimize redundant trips to the db when looking for module settings. - * Hooks that change module settings should run this function with - * $refresh = TRUE so other hooks can just get settings without a db - * query. + * Returns all module settings for the Google Appliance module. * - * @arg $refresh - * TRUE >> query the db for the settings - * - * @return - * a keyed array of module settings keyed by $field_keys + * @return array + * An associative array of module settings keyed by $field_keys. */ -function _google_appliance_get_settings($refresh = FALSE) { - - static $settings; - +function _google_appliance_get_settings() { $field_keys = array( 'hostname', 'collection', @@ -53,6 +45,7 @@ function _google_appliance_get_settings($refresh = FALSE) { 'timeout', 'autofilter', 'language_filter_toggle', + 'language_filter_options', 'query_inspection', 'search_title', 'results_per_page', @@ -69,35 +62,28 @@ function _google_appliance_get_settings($refresh = FALSE) { 'error_lib_xml_parse_error_format', ); - if ($refresh || empty($settings)) { - - // Settings fall back to default constants. - foreach ($field_keys as $field) { - $settings[$field] = variable_get( - 'google_appliance_' . $field, - constant('SGA_DEFAULT_' . strtoupper($field)) - ); - } - - // The default value of language_filter_options is an array, which - // cannot be used as a PHP constant. We set it here. - $settings['language_filter_options'] = variable_get( - 'google_appliance_language_filter_options', - array('***CURRENT_LANGUAGE***') + // Settings fall back to default constants. + foreach ($field_keys as $field) { + $settings[$field] = variable_get( + 'google_appliance_' . $field, + constant('SGA_DEFAULT_' . strtoupper($field)) ); + } - // Convert onebox_modules from string to array. - $settings['onebox_modules'] = explode("\n", $settings['onebox_modules']); - $settings['onebox_modules'] = array_map('trim', $settings['onebox_modules']); - $settings['onebox_modules'] = array_filter($settings['onebox_modules'], 'strlen'); - - // The empty string in the define block above for block visibility - // settings is really just a flag that nothing has been set yet. - // Using an empty string is problematic, so we just set it to an - // empty array instead. - if ($settings['block_visibility_settings'] === '') { - $settings['block_visibility_settings'] = array(); - } + // Convert onebox_modules from string to array. + $settings['onebox_modules'] = explode("\n", $settings['onebox_modules']); + $settings['onebox_modules'] = array_map('trim', $settings['onebox_modules']); + $settings['onebox_modules'] = array_filter($settings['onebox_modules'], 'strlen'); + + // The empty string in the define block above for block visibility + // settings is really just a flag that nothing has been set yet. + // Using an empty string is problematic, so we just set it to an + // empty array instead. + if ($settings['block_visibility_settings'] === '') { + $settings['block_visibility_settings'] = array(); + } + if ($settings['language_filter_options'] === '') { + $settings['language_filter_options'] = array(); } return $settings; diff --git a/google_appliance.module b/google_appliance.module index c1b39a8..d0d5399 100644 --- a/google_appliance.module +++ b/google_appliance.module @@ -249,7 +249,7 @@ function google_appliance_block_form_submit($form, &$form_state) { * conditionally hide content from the crawler using googleon/googleoff tags. */ function google_appliance_form_block_admin_configure_alter(&$form, &$form_state, $form_id) { - $settings = _google_appliance_get_settings(TRUE); + $settings = _google_appliance_get_settings(); // Determine the default value for this block. $default = 'none'; @@ -295,7 +295,7 @@ function google_appliance_form_block_admin_configure_alter(&$form, &$form_state, * Submit handler to save block-specific crawler visibility settings. */ function google_appliance_block_visibility_submit($form, &$form_state) { - $settings = _google_appliance_get_settings(TRUE); + $settings = _google_appliance_get_settings(); $module = $form_state['values']['module']; $delta = $form_state['values']['delta']; diff --git a/google_appliance.variable.inc b/google_appliance.variable.inc new file mode 100644 index 0000000..36517a9 --- /dev/null +++ b/google_appliance.variable.inc @@ -0,0 +1,207 @@ + t('Google Search Appliance'), + 'description' => t('Google Search Appliance settings and configuration'), + 'access' => 'administer_google_appliance', + 'path' => array('admin/config/search/google_appliance/settings'), + ); + + return $groups; +} + + +/** + * Implements hook_variable_info(). + */ +function google_appliance_variable_info($options) { + // Appliance hostname. + $variables['google_appliance_hostname'] = array( + 'title' => t('Google Search Appliance Host Name', array(), $options), + 'description' => t('Valid URL or IP address of the GSA device, including http:// or https://. Do not include /search at the end, or a trailing slash, but you should include a port number if needed. Example: http://my.gsabox.com:8443', array(), $options), + 'type' => 'string', + 'default' => SGA_DEFAULT_HOSTNAME, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Default collection. + $variables['google_appliance_collection'] = array( + 'title' => t('Collection', array(), $options), + 'description' => t('The name of a valid collection on the GSA device (case sensitive).', array(), $options), + 'type' => 'string', + 'default' => SGA_DEFAULT_COLLECTION, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Default frontend. + $variables['google_appliance_frontend'] = array( + 'title' => t('Frontend client', array(), $options), + 'description' => t('The name of a valid frontend client on the GSA device (case sensitive).', array(), $options), + 'type' => 'string', + 'default' => SGA_DEFAULT_FRONTEND, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Request timeout interval. + $variables['google_appliance_timeout'] = array( + 'title' => t('Search Timeout', array(), $options), + 'description' => t('Length of time to wait for response from the GSA device before giving up (timeout in seconds).', array(), $options), + 'type' => 'number', + 'default' => SGA_DEFAULT_TIMEOUT, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Auto-filtering. + $variables['google_appliance_autofilter'] = array( + 'title' => t('Search Results Auto-Filtering Options', array(), $options), + 'description' => t('Learn more about GSA auto-filtering here. In general, employing both filters enhances results, but sites with smaller indexes may suffer from over-filtered results.', array('@gsa-doc-af' => 'http://code.google.com/apis/searchappliance/documentation/68/xml_reference.html#request_filter_auto'), $options), + 'type' => 'options', + 'options' => array( + '0' => t('No filtering'), + 's' => t('Duplicate Directory Filter'), + 'p' => t('Duplicate Snippet Filter'), + '1' => t('Both Duplicate Directory and Duplicate Snippet Filters') + ), + 'default' => SGA_DEFAULT_AUTOFILTER, + 'group' => 'google_appliance', + ); + + // Language filter settings. + if (module_exists('locale')) { + // Toggle to enable/disable language filtering. + $variables['google_appliance_language_filter_toggle'] = array( + 'title' => t('Enable Language Filtering', array(), $options), + 'type' => 'boolean', + 'default' => SGA_DEFAULT_LANGUAGE_FILTER_TOGGLE, + 'group' => 'google_appliance', + ); + + // Language filter selection + $variables['google_appliance_language_filter_options'] = array( + 'title' => t('Restrict searches to specified languages', array(), $options), + 'description' => t('If there are no results in the specified language, the search appliance is expected to return results in all languages.', array(), $options), + 'type' => 'options', + 'options' => array( + '***CURRENT_LANGUAGE***' => t("Current user's language"), + '***DEFAULT_LANGUAGE***' => t("Default site language"), + ) + locale_language_list(), + 'default' => SGA_DEFAULT_LANGUAGE_FILTER_OPTIONS, + 'group' => 'google_appliance', + ); + } + + // Query inspection. + $variables['google_appliance_query_inspection'] = array( + 'title' => t('Enable Query Inspection', array(), $options), + 'description' => t('Inspect the search query parameters sent to the GSA device in the Drupal message area every time a search is performed. Only really useful for sites not using the Devel module, as dsm() provides more information. The inspector is only shown to administrators, but should be disabled in a production environment.', array(), $options), + 'type' => 'boolean', + 'default' => SGA_DEFAULT_QUERY_INSPECTION, + 'group' => 'google_appliance', + ); + + // Search page path. + $variables['google_appliance_search_title'] = array( + 'title' => t('Search path', array(), $options), + 'description' => t('The URL of the search page provided by this module. Include neither leading nor trailing slash.', array(), $options), + 'type' => 'string', + 'default' => SGA_DEFAULT_DRUPAL_PATH, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Search page title. + $variables['google_appliance_search_title'] = array( + 'title' => t('Search Name', array(), $options), + 'description' => t('Serves as the page title on results pages and the default menu item title', array(), $options), + 'type' => 'string', + 'default' => SGA_DEFAULT_SEARCH_TITLE, + 'required' => TRUE, + 'localize' => TRUE, + 'group' => 'google_appliance', + ); + + // Results per page. + $variables['google_appliance_results_per_page'] = array( + 'title' => t('Results per page', array(), $options), + 'description' => t('Number of results to show on the results page. More results will be available via a Drupal pager.', array(), $options), + 'type' => 'number', + 'default' => SGA_DEFAULT_RESULTS_PER_PAGE, + 'required' => TRUE, + 'group' => 'google_appliance', + ); + + // Spelling suggestions. + $variables['google_appliance_spelling_suggestions'] = array( + 'title' => t('Display Spelling Suggestions', array(), $options), + 'type' => 'boolean', + 'default' => SGA_DEFAULT_SPELLING_SUGGESTIONS, + 'group' => 'google_appliance', + ); + + // Search reporting. + $variables['google_appliance_advanced_search_reporting'] = array( + 'title' => t('Enable Advanced Search Reporting', array(), $options), + 'description' => t('Learn more about !this_feature. You need to enable Advanced Search Reporting on the front end client. The device should provide a file named "/clicklog_compiled.js" when using the search interface on the GSA.', array('!this_feature' => l(t('this feature'), 'http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/xml_reference/advanced_search_reporting.html')), $options), + 'type' => 'boolean', + 'default' => SGA_DEFAULT_SPELLING_SUGGESTIONS, + 'group' => 'google_appliance', + ); + + // Onebox modules. + $variables['google_appliance_onebox_modules'] = array( + 'title' => t('Onebox modules', array(), $options), + 'description' => t('A list of Onebox modules, one per line. Each module listed will have a corresponding block. These blocks must be placed via the block configuration page, or another layout mechanism like Context or Panels.', array(), $options), + 'type' => 'text', + 'default' => SGA_DEFAULT_ONEBOX_MODULES, + 'localize' => FALSE, + 'group' => 'google_appliance', + ); + + // No results error message. + $variables['google_appliance_error_gsa_no_results'] = array( + 'title' => t('No results error message', array(), $options), + 'description' => t('The message displayed to the user when no results are found for the given search query.', array(), $options), + 'type' => 'text', + 'default' => SGA_DEFAULT_ERROR_GSA_NO_RESULTS, + 'required' => TRUE, + 'localize' => TRUE, + 'group' => 'google_appliance', + ); + + // Connection error message. + $variables['google_appliance_error_curl_error'] = array( + 'title' => t('Connection error message', array(), $options), + 'description' => t('The message displayed to the user when there is an error connecting to the search appliance.', array(), $options), + 'type' => 'text', + 'default' => SGA_DEFAULT_ERROR_CURL_ERROR, + 'required' => TRUE, + 'localize' => TRUE, + 'group' => 'google_appliance', + ); + + // Parse error message. + $variables['google_appliance_error_lib_xml_parse_error'] = array( + 'title' => t('XML parse error message', array(), $options), + 'description' => t('The message displayed to the user when the XML returned by the appliance is malformed.', array(), $options), + 'type' => 'text', + 'default' => SGA_DEFAULT_ERROR_LIB_XML_PARSE_ERROR, + 'required' => TRUE, + 'localize' => TRUE, + 'group' => 'google_appliance', + ); + return $variables; +}