diff --git a/includes/TingSearchCqlDoctor.class.inc b/includes/TingSearchCqlDoctor.class.inc
new file mode 100644
index 0000000..47e55d0
--- /dev/null
+++ b/includes/TingSearchCqlDoctor.class.inc
@@ -0,0 +1,282 @@
+ portland and (film)
+ * henning mortensen (f. 1939) => henning and mortensen and "(f. 1939)"
+ * harry and (White night) = harry and "(White night)"
+ *
+ *
+ * Valid cql stays the same eg.
+ * dkcclterm.sf=v and dkcclterm.uu=nt and (term.type=bog) not term.literaryForm=fiktion
+ */
+
+/**
+ * Class TingSearchCqlDoctor.
+ *
+ * An attempt to convert non cql search phrases to valid cql.
+ */
+class TingSearchCqlDoctor {
+
+ /**
+ * @var string cql_string.
+ * Internael representation of the searchphtrase.
+ */
+ private $cql_string;
+ /**
+ * @var array pattern.
+ * The pattern to replace in searchstring.
+ */
+ private $pattern = array();
+ /**
+ * @var array replace.
+ * The string to replace with.
+ */
+ private $replace=array();
+ /**
+ * @var int replace_key.
+ * Used to prepend key - @see $this->get_replace_key().
+ */
+ private static $replace_key = 10;
+
+ /**
+ * Constructor,Escape reserved characters, remove multiple whitespaces
+ * and sets private member $cql_string with trimmed string.
+ *
+ * @param string $string
+ * The search phrase to cure.
+ */
+ public function __construct($string) {
+ $this->cql_string = trim($string);
+ // Remove multiple whitespaces.
+ $this->cql_string = preg_replace('/\s+/', ' ', $this->cql_string);
+ }
+
+ /**
+ * Method to convert a string to strict cql.
+ *
+ * Basically this method adds quotes when needed.
+ *
+ * @param string $string
+ * The search query.
+ * @return string
+ * Cql compatible string.
+ */
+ public function string_to_cql() {
+
+ // Handle qoutes.
+ $this->fix_qoutes();
+ // Hendle parantheses.
+ $this->fix_paranthesis();
+ // Handle reserved characters.
+ $this->escape_reserved_characters();
+ // Format the string.
+ return $this->format_cql_string();
+ }
+
+ /**
+ * Format cql string.
+ *
+ * Use private members $pattern and $replace to replace not valid cql phrases with valid.
+ *
+ * @return string
+ * string in valid cql (hopefully)
+ *
+ */
+ private function format_cql_string() {
+ // Last check. All parts of cql string must be valid.
+ $valid = TRUE;
+ $parts = preg_split($this->get_cql_operators_regexp(), $this->cql_string);
+ foreach ($parts as $part) {
+ if (!$this->string_is_cql($part)) {
+ $valid = FALSE;
+ break;
+ }
+ }
+ // Explode string by whitespace.
+ $expressions = explode(' ', $this->cql_string);
+
+ // Replace keys with phrases,
+ if (!empty($this->pattern)) {
+ $expressions = preg_replace($this->pattern, $this->replace, $expressions);
+ }
+
+ $done = FALSE;
+ do {
+ $expressions = $this->replace_inline($expressions, $done);
+ }
+ while(!$done);
+
+ // Remove empty elements.
+ $empty_slots = array_keys($expressions,'');
+ foreach($empty_slots as $slot){
+ unset($expressions[$slot]);
+ }
+
+ if ($valid) {
+ // Implode by blank.
+ return implode(' ', $expressions);
+ }
+
+ // String is not valid; implode by and.
+ return implode(' and ', $expressions);
+ }
+
+
+ /**
+ * Some replacements are nested in paranthesis and/or qoutes
+ * eg. (hund and "("hest")") which is perfectly legal.
+ * Cql doctor first handles the qoutes and then the
+ * paranthesis ; thus (hund and "("hest")") becomes encoded multiple times.
+ * This method runs through all parts to fix it
+ *
+ * @param array $expressions;
+ * The parts of the searchquery to be cured.
+ * @param $done;
+ * Flag indicating whether all parts has been handled.
+ * @return array;
+ * Decoded expressions.
+ */
+ private function replace_inline($expressions, &$done) {
+ foreach ($expressions as $key_exp => $expression) {
+ foreach ($this->pattern as $key_pat => $regexp) {
+ if (preg_match($regexp, $expression)) {
+ $expressions[$key_exp] = preg_replace($regexp, $this->replace[$key_pat], $expression);
+ return $expressions;
+ }
+ }
+ }
+ $done = TRUE;
+ return $expressions;
+ }
+
+
+ /**
+ * Enqoute forward slashes and '-'.
+ *
+ * @return nothing
+ * Alters private member cql_string.
+ */
+ private function escape_reserved_characters() {
+ $this->cql_string = str_replace('/', ' "/" ', $this->cql_string);
+ }
+
+ /**
+ * Get a key for replacement in string.
+ *
+ * @return string
+ */
+ private function get_replace_key() {
+ $key_prefix = 'zxcv';
+ return $key_prefix . self::$replace_key++;
+ }
+
+ /**
+ * Handle parantheses.
+ *
+ * Look lace parantheses in string. If any found and content is not
+ * strict cql; enqoute the lot.
+ *
+ * @return nothing.
+ * Alters private member cql_string.
+ *
+ */
+ private function fix_paranthesis() {
+ //Grab content in paranthesis.
+ preg_match_all('$\(([^\(\)]*)\)$', $this->cql_string, $phrases);
+
+ if (empty($phrases[1])) {
+ // No matching paranthesis.
+ return;
+ }
+
+ foreach ($phrases[1] as $key => $phrase) {
+ if (!$this->string_is_cql($phrase)) {
+ $this->set_replace_pattern($phrases[0][$key], TRUE);
+ }
+ else{
+ $this->set_replace_pattern($phrase);
+ }
+ }
+ }
+
+ /**
+ * Handle qoutes.
+ *
+ * Look for qouted content. Qouted content is replaced in searchstring.
+ */
+ private function fix_qoutes() {
+ // Greab qouted content.
+ preg_match_all('$"([^"]*)"$', $this->cql_string, $phrases);
+;
+ if (!empty($phrases[0])) {
+ foreach ($phrases[0] as $phrase) {
+ $this->set_replace_pattern($phrase);
+ }
+ }
+ }
+
+ /**
+ * Helper function to set a single replacement key and phrase.
+ *
+ * Adds given phrase to private member $replace. Retrieve a key for the replacement and replace given phrase in
+ * internal representation of search string with the key.
+ *
+ * @param string $phrase.
+ * The phrase to add to private member $replace.
+ * @param bool $qoute_me.
+ * If TRUE phrase is enqouted.
+ * @return nothing
+ * Alters private member cql_string
+ */
+ private function set_replace_pattern($phrase, $qoute_me = FALSE) {
+ if ($qoute_me) {
+ $this->replace[] = '"' . $phrase . '"';
+ }
+ else {
+ $this->replace[] = $phrase;
+ }
+ $replace_key = $this->get_replace_key();
+ $this->pattern[] = '/' . $replace_key . '/';
+
+ $this->cql_string = str_replace($phrase, $replace_key, $this->cql_string);
+ }
+
+
+ /**
+ * Tests if a string is cql.
+ *
+ * If string contains a cql operator it is assumed that an attempt to write cql is done.
+ *
+ * @param string $string
+ * The search query
+ * @return bool|int
+ * Whether the string is valid cql(TRUE) or not(FALSE)
+ */
+ private function string_is_cql($string) {
+ // Single word is valid (no whitespaces).
+ if (strpos(trim($string), ' ') === FALSE) {
+ return TRUE;
+ }
+ return preg_match($this->get_cql_operators_regexp(), $string);
+ }
+
+ /**
+ * Get reqular expression to ideniify cql operators.
+ *
+ * @return string.
+ * Reqular expression to identify cql operators.
+ */
+ private function get_cql_operators_regexp() {
+ return '@ and | any | all | adj | or | not |=|\(|\)@i';
+ }
+}
diff --git a/includes/ting_search.admin.inc b/includes/ting_search.admin.inc
new file mode 100644
index 0000000..de8aed8
--- /dev/null
+++ b/includes/ting_search.admin.inc
@@ -0,0 +1,79 @@
+ 'fieldset',
+ '#title' => t('Ting search settings'),
+ '#tree' => FALSE,
+ );
+
+ // Set ting search results per page. Used on the ting search page to determine
+ // the initial amount of search results to display.
+ $form['ting_search']['ting_search_results_per_page'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Default results per page'),
+ '#description' => t('Enter the number of results desplayed on the search page by default.'),
+ '#default_value' => variable_get('ting_search_results_per_page', 10),
+ );
+
+ // Set ting search number of facets. Used on the ting search page to determine
+ // how many facets to display in the facet browser.
+ $form['ting_search']['ting_search_number_of_facets'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Number of facets'),
+ '#description' => t('Enter the number of facets the search engine should show.'),
+ '#default_value' => variable_get('ting_search_number_of_facets', 25),
+ );
+
+ $form['ting_search']['ting_search_register_serie_title'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Serie title'),
+ '#description' => t('Specify the searchstring to be used for searching against serie titles. Use @serietitle as a placeholder for the serietitle'),
+ '#default_value' => variable_get('ting_search_register_serie_title', 'phrase.titleSeries="@serietitle"'),
+ );
+
+ // The default sort option. Used by ting search execute to set the default
+ // sort option.
+ $form['ting_search']['ting_search_default_sort'] = array(
+ '#type' => 'select',
+ '#title' => t('Default sorting'),
+ '#options' => ting_search_sort_options(),
+ '#default_value' => variable_get('ting_search_default_sort', ''),
+ '#description' => t('Set the default sorting for search results.'),
+ );
+
+ $form['ting_search']['ting_search_result_message'] = array(
+ '#type' => 'item',
+ '#attributes' => array('class' => array('description')),
+ '#title' => t('Display message'),
+ '#markup' => t($display_message),
+ '#description' => t('Message to display when search has more than x results. The token %s will be substituted by the number choosen.'),
+ );
+
+ if ( t($display_message) != $display_message ) {
+ $form['ting_search']['ting_search_result_message']['#description'] .= '
' . t('Translated from: %n.', array('%n' => $display_message));
+ }
+
+ $form['ting_search']['ting_search_result_message_limit'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Display message at'),
+ '#default_value' => variable_get('ting_search_result_message_limit', 100),
+ '#description' => t('The limit at wich the message is to be displayed.'),
+ );
+
+ return system_settings_form($form);
+}
diff --git a/js/ting_search.js b/js/ting_search.js
new file mode 100644
index 0000000..dfe4268
--- /dev/null
+++ b/js/ting_search.js
@@ -0,0 +1,62 @@
+(function($) {
+ "use strict";
+
+ $(document).ready(function() {
+ // Add overlay with spinner to search input fields while searching.
+ $('input[name="search_block_form"]').keydown(function(event) {
+ // When enter is hit in the search form.
+ if (event.which == 13) {
+ Drupal.TingSearchOverlay();
+ }
+ });
+
+ // Hook into the search button as well.
+ $('#search-block-form input[type="submit"]').click(function() {
+ Drupal.TingSearchOverlay();
+
+ return true;
+ });
+
+ // Add search link to the different links on the search result page.
+ $('.search-results a').live('click', function() {
+ if ($(this).not('[target="_blank"]').length) {
+ Drupal.TingSearchOverlay();
+ }
+ });
+ });
+
+ /**
+ * Add or remove spinner class to search block form wrapper.
+ *
+ * @param bool $state
+ * If TRUE the class spinner is added, FALSE it's removed.
+ */
+ function ting_search_toggle_spinner(state) {
+ $('.search-field-wrapper').toggleClass('spinner', state);
+ }
+
+ // Override default auto-complete to add spinner class.
+ Drupal.jsAC.prototype.setStatus = function (status) {
+ switch (status) {
+ case 'begin':
+ ting_search_toggle_spinner(true);
+ break;
+ case 'cancel':
+ case 'error':
+ case 'found':
+ ting_search_toggle_spinner(false);
+ break;
+ }
+ };
+
+ /**
+ * Override default auto-complete behavior that prevents form submit
+ */
+ Drupal.autocompleteSubmit = function () {
+ $('#autocomplete').each(function () {
+ this.owner.hidePopup();
+ });
+
+ return true;
+ };
+}(jQuery));
diff --git a/js/ting_search_backends.js b/js/ting_search_backends.js
new file mode 100644
index 0000000..b251593
--- /dev/null
+++ b/js/ting_search_backends.js
@@ -0,0 +1,33 @@
+(function($) {
+ "use strict";
+
+ /**
+ * This script handle the changes from the different backends, which
+ * currently is the data-well and the homepage. This in sures that action
+ * is taken when the labels or radios are clicked.
+ */
+ $(document).ready(function() {
+ // Click the label link when a radio button is clicked.
+ $('#ting-search-backend-engines-form input[type="radio"]').change(function() {
+ var link = $(this).parent().find('a');
+ Drupal.TingSearchOverlay();
+ window.location = link.attr('href');
+ });
+
+ // When a label link is click, also check the radio button.
+ $('#ting-search-backend-engines-form a').click(function(event) {
+ var radio = $(this).parent().parent().find('input[type="radio"]');
+ if (radio.is(':checked')) {
+ // If it is already checked do nothing.
+ event.preventDefault();
+ return false;
+ }
+ else {
+ // Check the radio button and continue handling the click event.
+ radio.attr('checked', 'checked');
+ Drupal.TingSearchOverlay();
+ return true;
+ }
+ });
+ });
+}(jQuery));
diff --git a/ting_search_extendform.js b/js/ting_search_extendform.js
similarity index 99%
rename from ting_search_extendform.js
rename to js/ting_search_extendform.js
index 6754da7..ef00349 100644
--- a/ting_search_extendform.js
+++ b/js/ting_search_extendform.js
@@ -8,7 +8,6 @@
$.TingExtendedForm = {};
$.TingExtendedForm.showExtended = false;
-
Drupal.behaviors.clearExtendForm = {
attach:function(context, settings) {
$('#extend-form-clear', context).click(function() {
@@ -78,5 +77,5 @@
}
};
-} (jQuery));
+}(jQuery));
diff --git a/js/ting_search_overlay.js b/js/ting_search_overlay.js
new file mode 100644
index 0000000..cc12c37
--- /dev/null
+++ b/js/ting_search_overlay.js
@@ -0,0 +1,61 @@
+/**
+ * @file
+ * Defines the ting search overlay and makes it available for other scripts.
+ */
+(function($) {
+ "use strict";
+
+ var ctrlKeyIsPressed = false;
+ // Ctrl or CMD key codes.
+ var keyCodes = [224, 17, 91, 93];
+
+ // Do not show overlay if ctrl key is pressed.
+ $('body').live('keydown keyup', function(e) {
+
+ var keyPressState = e.type == 'keydown' ? true : false;
+ if($.inArray(e.which, keyCodes) !== -1) {
+ ctrlKeyIsPressed = keyPressState;
+ }
+ });
+
+ /**
+ * Add search overlay function, so all search related JavaScripts can call it.
+ */
+ Drupal.TingSearchOverlay = function(remove_overlay) {
+
+ if (ctrlKeyIsPressed === false) {
+ // Try to get overlay
+ var overlay = $('.search-overlay--wrapper');
+ if (!overlay.length) {
+ // Overlay not found so create is and display.
+ overlay = $('
');
+ $('body').prepend(overlay);
+ }
+ else {
+ // Overlay found.
+ if (typeof remove_overlay !== 'undefined') {
+ // If toggle remove it.
+ overlay.remove();
+ }
+ }
+ }
+ };
+
+ // Hook into the overlays "Cancel" link and stop page loading if clicked.
+ $(document).ready(function() {
+ $('.search-overlay--wrapper .cancel').live('click', function() {
+ window.stop();
+ Drupal.TingSearchOverlay(true);
+ });
+
+ // Remove overlay on page unload, so it's not shown when back button is used
+ // in the browser.
+ $(window).unload(function() {
+ var overlay = $('.search-overlay--wrapper');
+ if (overlay.length) {
+ Drupal.TingSearchOverlay(true);
+ }
+ });
+ });
+
+}(jQuery));
diff --git a/js/ting_search_per_page.js b/js/ting_search_per_page.js
new file mode 100644
index 0000000..1c5b012
--- /dev/null
+++ b/js/ting_search_per_page.js
@@ -0,0 +1,18 @@
+(function($) {
+ "use strict";
+
+ $(document).ready(function() {
+ $('.pane-search-per-page select').change(function() {
+ // Display search overlay.
+ Drupal.TingSearchOverlay();
+
+ // Reloads the page when new size is selected in the drop-down.
+ $('#ting-search-per-page-form').trigger("submit");
+ });
+
+ $('.pane-ting-search-sort-form select').change(function() {
+ // Display search overlay.
+ Drupal.TingSearchOverlay();
+ });
+ });
+}(jQuery));
diff --git a/plugins/content_types/search_backends.inc b/plugins/content_types/search_backends.inc
new file mode 100644
index 0000000..f152457
--- /dev/null
+++ b/plugins/content_types/search_backends.inc
@@ -0,0 +1,117 @@
+ t('Ting search - backend engines'),
+ 'description' => t("Display the search engines as facets."),
+ 'single' => TRUE,
+ 'content_types' => array('ting_search'),
+ 'render callback' => 'ting_search_backend_engines_content_type_render',
+ 'category' => t('Ting'),
+ 'render last' => TRUE,
+ 'required context' => new ctools_context_required(t('Keywords'), 'string'),
+);
+
+/**
+ * Render the ting search results amount block.
+ */
+function ting_search_backend_engines_content_type_render($subtype, $conf, $panel_args, $context) {
+ $options = array();
+
+ // Find search backends.
+ $backends = search_get_info();
+ $default = search_get_default_module_info();
+ $default_value = $default['module'];
+
+ // Search keys.
+ $keys = NULL;
+ if (!empty($context) && isset($context->data)) {
+ $keys = $context->data;
+ }
+
+ // Create options for each backend.
+ foreach ($backends as $name => $backend) {
+ // Get conditions (facets etc.).
+ $conditions = NULL;
+ if (isset($backend['conditions_callback']) && function_exists($backend['conditions_callback'])) {
+ // Build an optional array of more search conditions.
+ $conditions = $backend['conditions_callback']($keys);
+ }
+
+ // Create search path.
+ $path = 'search/' . $backend['path'] . '/' . $keys;
+ if (empty($conditions['sort'])) {
+ // Remove sort condition, if is the empty string.
+ unset($conditions['sort']);
+ }
+
+ // Create the option as a link.
+ $txt = format_string('Search @backend', array('@backend' => $backend['title']));
+ $title = l(t($txt), $path, array('query' => $conditions));
+
+ // Set default value.
+ if (arg(1) == $backend['module']) {
+ $default_value = $backend['module'];
+ }
+
+ // Add default option to the start of the array.
+ if ($default['module'] == $backend['module']) {
+ array_unshift($options, $title);
+ }
+ else {
+ $options[$backend['module']] = $title;
+ }
+ }
+
+ // Create a form with the radio buttons.
+ $form = drupal_get_form('ting_search_backend_engines_form', $options, $default_value);
+
+ // Create the output.
+ $block = new stdClass();
+ $block->content = $form;
+
+ return $block;
+}
+
+/**
+ * Implements hook_form().
+ *
+ * Defines the select search engine backend with radio buttons.
+ */
+function ting_search_backend_engines_form($form, &$form_state, $options, $default) {
+ $form = array(
+ '#token' => FALSE,
+ '#attached' => array(
+ 'js' => array(
+ // Script to handle usability in the frontend (clicks).
+ drupal_get_path('module', 'ting_search') . '/js/ting_search_backends.js',
+ ),
+ ),
+ );
+
+ $form['backends'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Search in'),
+ );
+
+ $form['backends']['searches'] = array(
+ '#type' => 'radios',
+ '#required' => FALSE,
+ '#options' => $options,
+ '#default_value' => $default,
+ );
+
+ return $form;
+}
+
+/**
+ * Enable admin settings page.
+ */
+function ting_search_backend_engines_content_type_edit_form($form, &$form_state) {
+ return $form;
+}
+
diff --git a/plugins/content_types/search_per_page.inc b/plugins/content_types/search_per_page.inc
new file mode 100644
index 0000000..38b869d
--- /dev/null
+++ b/plugins/content_types/search_per_page.inc
@@ -0,0 +1,147 @@
+ t('Ting search - results per page'),
+ 'description' => t("Display results per page selector."),
+ 'content_types' => array('ting_search'),
+ 'render callback' => 'ting_search_per_page_content_type_render',
+ 'category' => t('Ting'),
+ 'required context' => new ctools_context_required(t('Keywords'), 'string'),
+ 'defaults' => array(
+ 'select_type' => array('dropdown'),
+ ),
+ 'render last' => TRUE,
+);
+
+/**
+ * Render the ting search results amount block.
+ */
+function ting_search_per_page_content_type_render($subtype, $conf, $panel_args, $context) {
+ $sizes = ting_search_records_per_page_controls_content();
+
+ $content = '';
+ if (!empty($sizes) && isset($conf['select_type'])) {
+ switch ($conf['select_type']) {
+ case 'list':
+ $items = array();
+ foreach ($sizes as $size) {
+ $items[] = array(
+ 'data' => l($size['text'], current_path(), array(
+ 'query' => $size['query'],
+ 'attributes' => array(
+ 'class' => ($size['selected'] == TRUE ? array('selected') : array('')),
+ ),
+ )),
+ );
+ }
+
+ $content = array(
+ '#theme' => 'item_list',
+ '#title' => t('Results on page:'),
+ '#attributes' => array(
+ 'class' => array('ting-search-records-per-page'),
+ ),
+ '#items' => $items,
+ );
+ break;
+
+ case 'dropdown':
+ $content = drupal_get_form('ting_search_per_page_form', $sizes);
+ break;
+ }
+ }
+
+ // Create the output.
+ $block = new stdClass();
+ $block->content = $content;
+
+ return $block;
+}
+
+/**
+ * Implements hook_form().
+ *
+ * Creates the select "number of results per page" form.
+ */
+function ting_search_per_page_form($form, &$form_state, $sizes) {
+ $form = array(
+ '#attached' => array(
+ 'js' => array(
+ // Script to handle usability in the frontend (clicks).
+ drupal_get_path('module', 'ting_search') . '/js/ting_search_per_page.js',
+ ),
+ ),
+ );
+
+ $options = array();
+ $default = array();
+ foreach ($sizes as $size) {
+ $options[$size['text']] = t('Number of search result per page: !num', array('!num' => $size['text']));
+
+ if ($size['selected'] == TRUE) {
+ $default = array($size['text']);
+ }
+ }
+
+ $form['size'] = array(
+ '#type' => 'select',
+ '#required' => FALSE,
+ '#options' => $options,
+ '#default_value' => $default,
+ );
+
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Size'),
+ '#states' => array(
+ 'visible' => array(':input[name="op"]' => array('value' => '')),
+ ),
+ );
+
+ return $form;
+}
+
+/**
+ * Process submitted data for records per page form.
+ */
+function ting_search_per_page_form_submit($form, &$form_state) {
+ $query = drupal_get_query_parameters();
+
+ if (isset($form_state['input']['size'])) {
+ $query = array('size' => $form_state['input']['size']) + $query;
+ }
+
+ $form_state['redirect'] = array(current_path(), array('query' => $query));
+}
+
+/**
+ * Enable admin settings page.
+ */
+function ting_search_search_per_page_content_type_edit_form($form, &$form_state) {
+ $form['select_type'] = array(
+ '#type' => 'select',
+ '#title' => 'Output type',
+ '#options' => array(
+ 'list' => 'HTML list',
+ 'dropdown' => 'Dropdown',
+ ),
+ '#default_value' => $form_state['conf']['select_type'],
+ );
+
+ return $form;
+}
+
+/**
+ * Submit handler for search form.
+ */
+function ting_search_search_per_page_content_type_edit_form_submit($form, &$form_state) {
+ foreach (array_keys($form_state['plugin']['defaults']) as $key) {
+ if (isset($form_state['values'][$key])) {
+ $form_state['conf'][$key] = $form_state['values'][$key];
+ }
+ }
+}
diff --git a/plugins/content_types/search_result.inc b/plugins/content_types/search_result.inc
index c602df7..ed723e2 100644
--- a/plugins/content_types/search_result.inc
+++ b/plugins/content_types/search_result.inc
@@ -1,32 +1,31 @@
TRUE,
- 'title' => t('Ting search - Search results'),
- #'icon' => 'icon_search.png',
- 'description' => t('The results of a search using keywords.'),
- 'required context' => new ctools_context_required(t('Keywords'), 'string'),
- 'category' => t('Widgets'),
- 'content_types' => array('search_result'),
- 'defaults' => array(
- 'type' => 'node',
- 'log' => TRUE,
- 'override_empty' => FALSE,
- 'empty_title' => '',
- 'empty' => '',
- 'empty_format' => filter_fallback_format(),
- 'override_no_key' => FALSE,
- 'no_key_title' => '',
- 'no_key' => '',
- 'no_key_format' => filter_fallback_format(),
- ),
- );
-}
+$plugin = array(
+ 'single' => TRUE,
+ 'title' => t('Ting search - Search results'),
+ 'description' => t('The results of a search using keywords.'),
+ 'required context' => new ctools_context_required(t('Keywords'), 'string'),
+ 'category' => t('Widgets'),
+ 'content_types' => array('search_result'),
+ 'defaults' => array(
+ 'type' => 'node',
+ 'log' => TRUE,
+ 'override_empty' => FALSE,
+ 'empty_title' => '',
+ 'empty' => '',
+ 'empty_format' => filter_fallback_format(),
+ 'override_no_key' => FALSE,
+ 'no_key_title' => '',
+ 'no_key' => '',
+ 'no_key_format' => filter_fallback_format(),
+ ),
+ 'render first' => TRUE,
+ 'render last' => FALSE,
+);
/**
* Render the custom content type.
@@ -43,7 +42,7 @@ function ting_search_search_result_content_type_render($subtype, $conf, $panel_a
$keys = $context->data;
}
- $conditions = NULL;
+ $conditions = NULL;
if (isset($info['conditions_callback']) && function_exists($info['conditions_callback'])) {
// Build an optional array of more search conditions.
$conditions = $info['conditions_callback']($keys);
@@ -52,6 +51,7 @@ function ting_search_search_result_content_type_render($subtype, $conf, $panel_a
// Display nothing at all if no keywords were entered.
if (empty($keys) && empty($conditions)) {
if (!empty($conf['override_no_key'])) {
+ $block = new stdClass();
$block->title = $conf['no_key_title'];
$block->content = check_markup($conf['no_key'], $conf['no_key_format'], FALSE);
return $block;
@@ -61,13 +61,12 @@ function ting_search_search_result_content_type_render($subtype, $conf, $panel_a
// Build the content type block.
$block = new stdClass();
- $block->module = 'search';
- $block->delta = 'result';
+ $block->module = 'search';
+ $block->delta = 'result';
$results = '';
// Only search if there are keywords or non-empty conditions.
if ($keys || !empty($conditions)) {
-
// Collect the search results.
$results = search_data($keys, $info['module'], $conditions);
}
@@ -78,15 +77,32 @@ function ting_search_search_result_content_type_render($subtype, $conf, $panel_a
}
if (!empty($results['#results'])) {
- $output = "\n";
- foreach ($results['#results'] as $result) {
- $output .= theme('search_result', array('result' => $result, 'module' => $conf['type']));
+ // Get message limit and raw data well search results.
+ $limit = variable_get('ting_search_result_message_limit', 100);
+ $search_result = drupal_static('ting_search_results');
+
+ // Set message.
+ $message = '';
+
+ $frequency_rank = array(
+ 'rank_main_title' => t('Title'),
+ 'rank_creator' => t('Creator'),
+ 'rank_subject' => t('Subject')
+ );
+ if (isset($search_result) && in_array($search_result->sortUsed, array_keys($frequency_rank))) {
+ $msg = t('Records are sorted by %sortUsed . Select another sort if it is not suited', array('%sortUsed' => $frequency_rank[$search_result->sortUsed]));
+ $message .= '' . $msg . '
';
+ }
+
+
+ if (isset($search_result) && $limit < $search_result->numTotalObjects) {
+ $msg = t('Your search gave more than %s results. Try to search more specific or use the facets to filter the result.');
+ $msg = sprintf($msg, $limit);
+ $message .= '' . $msg . '
';
}
- $output .= "
\n";
- $output .= theme('ting_search_pager', array('tags' => NULL,));
$block->title = t('Search results');
- $block->content = $output;
+ $block->content = $message . theme('ting_search_results', array('results' => $results['#results'], 'module' => $conf['type']));;
}
else {
if (empty($conf['override_empty'])) {
@@ -153,7 +169,6 @@ function ting_search_search_result_content_type_edit_form($form, &$form_state) {
'#title' => t('Display text if no search keywords were submitted'),
);
-
$form['no_key_title'] = array(
'#title' => t('Title'),
'#type' => 'textfield',
diff --git a/plugins/content_types/search_result_count.inc b/plugins/content_types/search_result_count.inc
new file mode 100644
index 0000000..78c628c
--- /dev/null
+++ b/plugins/content_types/search_result_count.inc
@@ -0,0 +1,45 @@
+ t('Ting search - page title'),
+ 'description' => t("Display title with result count."),
+ 'content_types' => array('ting_search'),
+ 'render callback' => 'ting_search_result_count_content_type_render',
+ 'category' => t('Ting'),
+ 'required context' => new ctools_context_required(t('Keywords'), 'string'),
+ 'render last' => TRUE,
+);
+
+/**
+ * Render the ting search results amount block.
+ */
+function ting_search_result_count_content_type_render($subtype, $conf, $panel_args, $context) {
+ $block = new stdClass();
+
+ $search_result = drupal_static('ting_search_results');
+ if (isset($search_result)) {
+ $results = isset($search_result->numTotalObjects) ? (int) $search_result->numTotalObjects : 0;
+ $string = format_plural($results > 1 ? $results : 1, 'Result', 'Results');
+ $block->content = array(
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#markup' => t('Search result (!count !string)', array(
+ '!count' => $results,
+ '!string' => $string,
+ )),
+ );
+ }
+
+ return $block;
+}
+
+/**
+ * Enable admin settings page.
+ */
+function ting_search_search_result_count_content_type_edit_form($form, &$form_state) {
+ return $form;
+}
diff --git a/plugins/content_types/ting_search.inc b/plugins/content_types/ting_search.inc
index e35f61d..99912d6 100644
--- a/plugins/content_types/ting_search.inc
+++ b/plugins/content_types/ting_search.inc
@@ -2,7 +2,7 @@
$plugin = array(
'title' => t('Ting search - search results text'),
- 'description' => t('Show a string with \'Showing x - y of z results'),
+ 'description' => t("Show a string with 'Showing x - y of z results'"),
'single' => TRUE,
'content_types' => array('ting_search'),
'render callback' => 'ting_search_content_type_render',
@@ -19,22 +19,23 @@ function ting_search_content_type_render($subtype, $conf, $panel_args, $context)
if ($pager_total[0] == TRUE) {
$results = drupal_static('ting_search_results');
- $from = ($pager_page_array[0] < 1 ? 1 : ($pager_page_array[0])*$results->numTotalCollections+1);
- $to = $from + ($results->numTotalCollections-1);
+ $from = ($pager_page_array[0] < 1 ? 1 : ($pager_page_array[0]) * $results->numTotalCollections + 1);
+ $to = $from + ($results->numTotalCollections - 1);
$total = $results->numTotalObjects;
$block->title = t('Search results text');
$block->content = '' . format_plural($total,
'Show %from-%to of 1 result',
- 'Show %from-%to of @count results', array(
+ 'Show %from-%to of @count results', array(
'%from' => $from,
'%to' => $to,
- )) . '
';
+ )
+ ) . '';
}
return $block;
}
/**
- * Enable admin settings page
+ * Enable admin settings page.
*/
function ting_search_ting_search_content_type_edit_form($form, &$form_state) {
return $form;
diff --git a/templates/ting-search-display-extended-query.tpl.php b/templates/ting-search-display-extended-query.tpl.php
new file mode 100644
index 0000000..88d6f48
--- /dev/null
+++ b/templates/ting-search-display-extended-query.tpl.php
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/ting-search-extended-search.tpl.php b/templates/ting-search-extended-search.tpl.php
similarity index 63%
rename from ting-search-extended-search.tpl.php
rename to templates/ting-search-extended-search.tpl.php
index 2ef3a3d..e370a6f 100644
--- a/ting-search-extended-search.tpl.php
+++ b/templates/ting-search-extended-search.tpl.php
@@ -1,6 +1,4 @@
-
diff --git a/ting-search-results.tpl.php b/templates/ting-search-results.tpl.php
similarity index 90%
rename from ting-search-results.tpl.php
rename to templates/ting-search-results.tpl.php
index 780d587..c9d9b2f 100644
--- a/ting-search-results.tpl.php
+++ b/templates/ting-search-results.tpl.php
@@ -1,6 +1,4 @@
+ '(term.acquisitionDate=201528* OR dkcclterm.kk=bkm201528*
+ OR term.acquisitionDate=201529* OR dkcclterm.kk=bkm201529*
+ OR term.acquisitionDate=20153* OR dkcclterm.kk=bkm20153*)
+ AND facet.date=2015 AND dkcclterm.dk=77.7 AND dkcclterm.ma=th',
+
+ '(term.acquisitionDate=20153* OR dkcclterm.kk=bkm20153*)
+ AND facet.date=2015 AND dkcclterm.dk=sk AND (dkcclterm.ma=ro
+ OR dkcclterm.ma=no) AND dkcclterm.ma=xx NOT (dkcclterm.em=krimi
+ OR dkcclterm.ma=ss OR facet.category=børnematerialer)'
+ =>
+ '(term.acquisitionDate=20153* OR dkcclterm.kk=bkm20153*)
+ AND facet.date=2015 AND dkcclterm.dk=sk AND (dkcclterm.ma=ro
+ OR dkcclterm.ma=no) AND dkcclterm.ma=xx NOT (dkcclterm.em=krimi
+ OR dkcclterm.ma=ss OR facet.category=børnematerialer)',
+
+ '(term.acquisitionDate=20153* OR dkcclterm.kk=bkm20153*)
+ AND facet.date=2015 AND dkcclterm.ma=xx NOT (dkcclterm.em=krimi
+ OR dkcclterm.ma=ss OR facet.category=børnematerialer
+ OR dkcclterm.dk=sk OR dkcclterm.ma=ro OR dkcclterm.ma=no OR facet.dk5=79.41)'
+ =>
+ '(term.acquisitionDate=20153* OR dkcclterm.kk=bkm20153*)
+ AND facet.date=2015 AND dkcclterm.ma=xx NOT (dkcclterm.em=krimi
+ OR dkcclterm.ma=ss OR facet.category=børnematerialer
+ OR dkcclterm.dk=sk OR dkcclterm.ma=ro OR dkcclterm.ma=no OR facet.dk5=79.41)',
+
+ '(term.subject=fantasy OR term.subject="science fiction")
+ and (facet.type=dvd OR facet.type=blu*)'
+ =>
+ '(term.subject=fantasy OR term.subject="science fiction")
+ and (facet.type=dvd OR facet.type=blu*)',
+
+ 'facet.category="voksenmaterialer" AND term.type="bog"
+ AND term.subject=("gys" OR "overnaturlige evner")'
+ =>
+ 'facet.category="voksenmaterialer" AND term.type="bog"
+ AND term.subject=("gys" OR "overnaturlige evner")',
+
+ 'term.type="bog" AND facet.category="voksenmaterialer"
+ NOT dkcclterm.dk=(82* OR 83* OR 84* OR 85* OR 86* OR 87* OR 88*)'
+ =>
+ 'term.type="bog" AND facet.category="voksenmaterialer"
+ NOT dkcclterm.dk=(82* OR 83* OR 84* OR 85* OR 86* OR 87* OR 88*)',
+
+ 'rec.id = 870970-basis:05203120 OR rec.id=870970-basis:05203120'
+ =>
+ 'rec.id = 870970-basis:05203120 OR rec.id=870970-basis:05203120',
+
+ 'em any "delebørn skilsmissebørn"' => 'em any "delebørn skilsmissebørn"',
+
+ 'blue-ray' => 'blue-ray',
+ );
+}
+
+function ting_search_test_invalid_cql() {
+ return array(
+ 'anders and' => 'anders and and',
+
+ 'anders AND' => 'anders and AND',
+
+ '"anders and" phrase.title=ander*'
+ =>
+ '"anders and" and phrase.title=ander*',
+
+ 'anders AND (dc.title=historie)'
+ =>
+ 'anders AND (dc.title=historie)',
+
+ 'hest fisk hund' => 'hest and fisk and hund',
+ 'hest fisk and hund' => 'hest and fisk and and and hund',
+ 'blue/ray' => 'blue and "/" and ray',
+ );
+}
\ No newline at end of file
diff --git a/ting_search.test b/tests/ting_search.test
similarity index 81%
rename from ting_search.test
rename to tests/ting_search.test
index 7cd7512..d8b419b 100644
--- a/ting_search.test
+++ b/tests/ting_search.test
@@ -16,8 +16,6 @@ class TingSearchTestCase extends DrupalWebTestCase {
parent::setUp('ting', 'ding_entity', 'search', 'ting_search', 'nanosoap');
variable_set('ting_agency', '100200');
variable_set('ting_search_url', 'http://opensearch.addi.dk/next_2.0/');
- variable_set('ting_scan_url', 'http://openscan.addi.dk/1.5/');
- variable_set('ting_spell_url', 'http://openspell.addi.dk/1.2/');
variable_set('ting_recommendation_url', 'http://openadhl.addi.dk/1.1/');
variable_set('search_active_modules', array('ting_search' => 'ting_search'));
variable_set('ting_search_profile', 'opac');
@@ -174,6 +172,35 @@ class TingSearchParsingTestCase extends DrupalUnitTestCase {
'dc.title' => 'flammernes pokal',
),
),
+ // Regression tests.
+ array(
+ 'string' => 'banana and (dk=sk)',
+ 'keys' => array('term.creator', 'term.title', 'term.subject'),
+ 'expected' => array(
+ 'q' => 'banana and (dk=sk)',
+ ),
+ ),
+ array(
+ 'string' => 'banana AND (dk=sk)',
+ 'keys' => array('term.creator', 'term.title', 'term.subject'),
+ 'expected' => array(
+ 'q' => 'banana and (dk=sk)',
+ ),
+ ),
+ array(
+ 'string' => '(dk=sk)',
+ 'keys' => array('term.creator', 'term.title', 'term.subject'),
+ 'expected' => array(
+ 'q' => '(dk=sk)',
+ ),
+ ),
+ array(
+ 'string' => '(term.type="bog" OR term.type="ebog") AND (term.subject="fantasy" OR term.subject="krimi")',
+ 'keys' => array('term.creator', 'term.title', 'term.subject'),
+ 'expected' => array(
+ 'q' => '(term.type="bog" OR term.type="ebog") and (term.subject="fantasy" OR term.subject="krimi")',
+ ),
+ ),
);
foreach ($testCases as $test) {
drupal_static_reset('ting_search_extract_indexes');
@@ -187,45 +214,30 @@ class TingSearchParsingTestCase extends DrupalUnitTestCase {
function testQuoting() {
drupal_load('module', 'ting_search');
- $testCases = array(
- array(
- 'string' => 'anders and',
- 'expected' => 'anders "and"',
- ),
- array(
- 'string' => 'anders aNd',
- 'expected' => 'anders "aNd"',
- ),
- array(
- // This might seem like a pretty simple case, but this is actually a
- // regression test for an issue not caught by the more advanced tests.
- 'string' => 'anders AND',
- 'expected' => 'anders AND',
- ),
- array(
- 'string' => 'anders and AND (dc.title=historie)',
- 'expected' => 'anders "and" AND (dc.title=historie)',
- ),
- array(
- 'string' => 'anders AND (dc.title=historie)',
- 'expected' => 'anders AND (dc.title=historie)',
- ),
- array(
- 'string' => '"anders and" (dc.title=historie)',
- 'expected' => '"anders and" (dc.title=historie)',
- ),
- array(
- 'string' => '"anders \"and\"" (dc.title=historie)',
- 'expected' => '"anders \"and\"" (dc.title=historie)',
- ),
+ require_once "strings_for_cql_test.php";
- );
- foreach ($testCases as $test) {
- $res = _ting_search_quote($test['string']);
- $this->assertEqual($res, $test['expected'], 'Properly quoted: ' . $test['string']);
- if ($res != $test['expected']) {
+ $testCases = ting_search_test_valid_cql();
+
+ foreach ($testCases as $search => $expected) {
+ $res = _ting_search_quote($search);
+ $string = preg_replace( "/\r|\n/", "", $search );
+ $result = preg_replace( "/\r|\n/", "", $expected );
+ $this->assertEqual($string,$result , 'Properly quoted: ' . $search);
+ if ($string != $result) {
+ debug($res);
+ }
+ }
+
+ $testCases = ting_search_test_invalid_cql();
+
+ foreach ($testCases as $search => $expected) {
+ $res = _ting_search_quote($search);
+ $this->assertEqual($res,$expected , 'Properly quoted: ' . $search);
+ if ($res != $expected) {
debug($res);
+ debug($search);
}
}
+
}
}
diff --git a/ting-search-display-extended-query.tpl.php b/ting-search-display-extended-query.tpl.php
deleted file mode 100644
index a18a15f..0000000
--- a/ting-search-display-extended-query.tpl.php
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
diff --git a/ting_search.info b/ting_search.info
index c1b7f97..5933e14 100644
--- a/ting_search.info
+++ b/ting_search.info
@@ -4,7 +4,6 @@ package = Ding!
version = "7.x-0.26"
core = 7.x
files[] = ting_search.module
-files[] = ting_search.test
+files[] = tests/ting_search.test
dependencies[] = ting
dependencies[] = search
-stylesheets[all][] = ting_search.css
diff --git a/ting_search.make b/ting_search.make
index c0e49fb..b904ae6 100644
--- a/ting_search.make
+++ b/ting_search.make
@@ -5,4 +5,4 @@ core = 7.x
projects[ting][type] = "module"
projects[ting][download][type] = "git"
projects[ting][download][url] = "git@github.com:ding2/ting.git"
-projects[ting][download][tag] = "7.x-0.22"
+projects[ting][download][branch] = "master"
diff --git a/ting_search.module b/ting_search.module
index 6cef62d..196e235 100644
--- a/ting_search.module
+++ b/ting_search.module
@@ -1,10 +1,21 @@
1);
}
}
+
+/**
+ * Implements hook_menu().
+ */
+function ting_search_menu() {
+ $items = array();
+
+ $items['admin/config/ting/search'] = array(
+ 'title' => 'Search settings',
+ 'description' => 'Settings avialable for ting search.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('ting_search_admin_settings'),
+ 'access arguments' => array('administer ting settings'),
+ 'file' => 'includes/ting_search.admin.inc',
+ );
+
+ $items['search-blank'] = array(
+ 'callback' => '_blank_page',
+ 'access' => TRUE,
+ 'type' => MENU_CALLBACK,
+ );
+
+ return $items;
+}
+
+/**
+ * Menu callback to fix the twice search issue.
+ *
+ * When the search form is submitted back to Drupal it's submitted back to the
+ * same page. So a search performed on the search page will trigger the first
+ * search and the new search (twice search).
+ *
+ * @see http://platform.dandigbib.org/issues/372
+ */
+function _blank_page() {
+ return '';
+}
+
/**
* Implements hook_menu_alter().
*
* Temporary hack to alter titles.
*/
function ting_search_menu_alter(&$items) {
- $items['search/node']['title'] = 'Hjemmeside';
- $items['search/node/%menu_tail']['title'] = 'Hjemmeside';
+ $items['search/node']['title'] = 'Homepage';
+ $items['search/node/%menu_tail']['title'] = 'Homepage';
$items['search/node/%menu_tail']['load arguments'] = array('%map', '%index');
- $items['search/ting']['title'] = 'Brønd';
- $items['search/ting/%menu_tail']['title'] = 'Brønd';
+ $items['search/ting']['title'] = 'Data well';
+ $items['search/ting/%menu_tail']['title'] = 'Data well';
$items['search/meta/%menu_tail']['load arguments'] = array('%map', '%index');
$items['search/meta']['title'] = 'Universal Search';
$items['search/meta/%menu_tail']['title'] = 'Universal Search';
@@ -57,79 +106,96 @@ function ting_search_search_info() {
* Implements hook_ding_facetbrowser().
*/
function ting_search_ding_facetbrowser() {
- $results = new stdClass();
+ $results = new stdClass();
$results->show_empty = FALSE;
- $search_result = drupal_static('ting_search_results');
+ $search_result = drupal_static('ting_search_results');
if ($search_result) {
- $results->facets = ($search_result instanceof TingClientSearchResult) ? $search_result->facets : array();
- $results->searchkey = $search_result->search_key;
+ $results->facets = ($search_result instanceof TingClientSearchResult) ? $search_result->facets : array();
+ $results->searchkey = $search_result->search_key;
return $results;
}
}
-/**
- * Implements hook_entity_info_alter().
- */
-function ting_search_entity_info_alter(&$entity_info) {
- $entity_info['ting_collection']['view modes'] += array(
- 'search_result' => array(
- 'label' => t('Search result'),
- 'custom settings' => FALSE,
- ),
- );
-}
-
/**
* Implements hook_theme().
*/
-function ting_search_theme() {
+function ting_search_theme($existing, $type, $theme, $path) {
return array(
'ting_search_results' => array(
'variables' => array('results' => NULL, 'module' => NULL),
'file' => 'ting_search.pages.inc',
- 'template' => 'ting-search-results',
+ 'template' => 'templates/ting-search-results',
),
'ting_search_mini_pager' => array(
- 'variables' => array('tags' => array(), 'element' => 0, 'parameters' => array(), 'quantity' => 9),
+ 'variables' => array(
+ 'tags' => array(),
+ 'element' => 0,
+ 'parameters' => array(),
+ 'quantity' => 9,
+ ),
),
'ting_search_pager' => array(
- 'variables' => array('tags' => array(), 'element' => 0, 'parameters' => array(), 'quantity' => 9),
+ 'variables' => array(
+ 'tags' => array(),
+ 'element' => 0,
+ 'parameters' => array(),
+ 'quantity' => 9,
+ ),
),
'ting_search_display_extended_query' => array(
- 'variables' => array('query_label'=>NULL,'query_string' => NULL),
+ 'variables' => array('query_label' => NULL,'query_string' => NULL),
'template' => 'ting-search-display-extended-query',
+ 'path' => $path . '/templates',
),
'ting_search_extended_search' => array(
'template' => 'ting-search-extended-search',
+ 'path' => $path . '/templates',
),
);
}
+/**
+ * Returns a themed list of extended actions.
+ *
+ * @return string
+ * HTML ting_search_extended_search.
+ */
function ting_search_get_extended_actions() {
return theme('ting_search_extended_search');
}
/**
- * @brief Implementation of hook_form_FORM_ID_alter() for form search_block_form.
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * For the form search_block_form.
*/
function ting_search_form_search_block_form_alter(&$form, &$form_state, $form_id) {
+ // Define advanced fields.
$advanced_fields = array(
- 'dc.creator' => array(
+ 'term.creator' => array(
'key' => 'creator',
'title' => t('Author'),
'description' => t('Enter the author name'),
),
- 'dc.title' => array(
+ 'term.title' => array(
'key' => 'title',
'title' => t('Title'),
'description' => t('Enter title'),
),
- 'dc.subject' => array(
+ 'term.subject' => array(
'key' => 'subject',
'title' => t('Subject'),
'description' => t('Enter subject keywords'),
),
);
+
+ // Remove the form token so the form becomes cachable. If we don't, all
+ // pages with the search form becomes un-cachable, as drupal_validate_form()
+ // will check the token and fail if the current user is not the same as the
+ // one that caused the page to be cached.
+ unset($form['#token']);
+ unset($form['form_token']);
+
// We're going to disable advanced search in
// the first version, and implement later on.
// When implementing againg, set
@@ -140,6 +206,7 @@ function ting_search_form_search_block_form_alter(&$form, &$form_state, $form_id
// Parse extended search query parameters.
if (arg(0) == 'search') {
$parts = explode('/', $_GET['q']);
+
// Lose 'search' and the search type.
array_shift($parts);
$type = array_shift($parts);
@@ -147,15 +214,27 @@ function ting_search_form_search_block_form_alter(&$form, &$form_state, $form_id
$indexes = ting_search_extract_keys($search_query, array_keys($advanced_fields));
$search_query = $indexes['q'];
unset($indexes['q']);
+
if ($type != 'ting' and !empty($indexes)) {
$search_query .= " " . implode(' ', $indexes);
$indexes = array();
$advanced = FALSE;
}
+ // Set default value to the current search query.
$form['search_block_form']['#default_value'] = $search_query;
}
+ // Set max length on search input. This is need when users uses CQL search
+ // string as they can get very long. This length is base on experience from
+ // ding1 as seams to be long enough.
+ $form['search_block_form']['#maxlength'] = 1024;
+
+ // Add JS to handle spinner in the search form.
+ $form['search_block_form']['#attached']['js'] = array(
+ drupal_get_path('module', 'ting_search') . '/js/ting_search.js',
+ );
+
$form['sort'] = array(
'#type' => 'hidden',
'#default_value' => isset($_GET['sort']) ? check_plain($_GET['sort']) : FALSE,
@@ -163,11 +242,11 @@ function ting_search_form_search_block_form_alter(&$form, &$form_state, $form_id
);
$form['size'] = array(
'#type' => 'hidden',
- '#default_value' => isset($_GET['size']) ? (int)$_GET['size'] : FALSE,
+ '#default_value' => isset($_GET['size']) ? (int) $_GET['size'] : FALSE,
'#attributes' => array('id' => 'controls_search_size'),
);
- // See line 127-130 - disable in the first version
+ // See line 127-130 - disabled in the first version.
//$form['form_id']['#suffix'] = ting_search_get_extended_actions();
if ($advanced) {
@@ -180,39 +259,43 @@ function ting_search_form_search_block_form_alter(&$form, &$form_state, $form_id
'#prefix' => '',
'#suffix' => '
',
'#attached' => array(
- 'css' => array(
- drupal_get_path('module', 'ting_search') . '/ting_search_extendform.css',
- ),
'js' => array(
- drupal_get_path('module', 'ting_search') . '/ting_search_extendform.js',
+ drupal_get_path('module', 'ting_search') . '/js/ting_search_extendform.js',
),
),
);
- $expand = FALSE;
foreach ($advanced_fields as $name => $field) {
$form['advanced'][$field['key']] = array(
'#type' => 'textfield',
- '#title' => $field['title'],
+ '#title' => check_plain($field['title']),
'#size' => 30,
'#maxlength' => 64,
- '#description' => $field['description'],
+ '#description' => check_plain($field['description']),
'#default_value' => isset($indexes[$name]) ? $indexes[$name] : '',
);
}
}
$form['#submit'] = array('ting_search_submit');
+ // This submits the form to a blank page and prevents the search to be
+ // executed twice. See http://platform.dandigbib.org/issues/372 for more
+ // information.
+ $form['#action'] = '?q=search-blank';
+
return $form;
}
/**
* Extract special field keys from search string.
*
- * @param string $search_query The search query.
- * @param array $keys Keys to extract.
+ * @param string $search_query
+ * The search query.
+ * @param array $keys
+ * Keys to extract.
*
- * @return array Where the array keys are the search keys, and the remainder
+ * @return array
+ * Where the array keys are the search keys, and the remainder
* search string in 'q'.
*/
function ting_search_extract_keys($search_query, $keys) {
@@ -226,12 +309,14 @@ function ting_search_extract_keys($search_query, $keys) {
$search_query = preg_replace_callback($regexp, 'ting_search_extract_indexes', $search_query);
}
+ // Remove any leading and's.
+ $search_query = preg_replace('/^ and \\(/', '(', $search_query);
$indexes['q'] = $search_query;
return $indexes;
}
/**
- * preg_replace_callback function.
+ * Preg_replace_callback function.
*/
function ting_search_extract_indexes($matches, $set_keys = NULL) {
static $keys;
@@ -242,15 +327,15 @@ function ting_search_extract_indexes($matches, $set_keys = NULL) {
$subexps = preg_split('/\s+and\s+/i', $matches[2], NULL, PREG_SPLIT_NO_EMPTY);
$indexes = &drupal_static(__FUNCTION__, array());
foreach ($subexps as $subexp) {
- if ((preg_match('/^([^=]+)\=([^"]*)$/', $subexp, $rx) || preg_match('/^([^=]+)\="(.*)"$/', $subexp, $rx)) && array_key_exists(trim($rx[1]), $keys)) {
+ if ((preg_match('/^([^=]+)\=([^"]*)$/', $subexp, $rx) || preg_match('/^([^=]+)\="([^"]*)"$/', $subexp, $rx)) && array_key_exists(trim($rx[1]), $keys)) {
$indexes[trim($rx[1])] = trim($rx[2]);
}
else {
$return[] = $subexp;
}
}
- // Reappend unknown stuff.
- if (sizeof($return)) {
+ // Re-append unknown stuff.
+ if (count($return)) {
return " and (" . implode(' and ', $return) . ")";
}
return "";
@@ -267,14 +352,16 @@ function ting_search_conditions_callback($keys) {
}
if (!empty($_REQUEST['size'])) {
- $conditions['size'] = (int)$_REQUEST['size'];
+ $conditions['size'] = (int) $_REQUEST['size'];
}
if (!empty($_REQUEST['sort'])) {
$conditions['sort'] = check_plain($_REQUEST['sort']);
}
-
+ else {
+ $conditions['sort'] = variable_get('ting_search_default_sort', '');
+ }
// If facets is set, check if we have to remove any, if so,
// reload the page.
if (!empty($_REQUEST['facets'])) {
@@ -300,7 +387,7 @@ function ting_search_conditions_callback($keys) {
if ($redirect === TRUE) {
$facets = array();
foreach ($conditions['facets'] as $facet) {
- $facets['facets'][] = $facet;
+ $facets['facets'][] = $facet;
}
drupal_goto(rawurldecode($_GET['q']), array('query' => $facets));
}
@@ -312,67 +399,91 @@ function ting_search_conditions_callback($keys) {
* Implements hook_search_execute().
*/
function ting_search_search_execute($keys = NULL, $conditions = NULL) {
- // TODO: Set sort options
- $options = array();
- $results = array();
- $facetArray = array();
- $query = '(' . _ting_search_quote($keys) . ')';
- $options['numFacets'] = 25;
- module_load_include('client.inc', 'ting');
- //Extend query with selected facets
- if (isset($conditions['facets']) && $conditions['facets'] != NULL) {
- $facets = $conditions['facets'];
- foreach ($facets as $facet) {
- $facet = explode(':', $facet, 2);
- if ($facet[0]) {
- $facetArray[] = $facet[0] . '="' . rawurldecode($facet[1]) . '"';
+ // Use static variable to ensure that this is only executed once.
+ $results = &drupal_static(__FUNCTION__);
+ if (!isset($results)) {
+ $results = array();
+ $options = array();
+ $results = array();
+ $facet_array = array();
+ $query = '(' . _ting_search_quote($keys) . ')';
+ $options['numFacets'] = variable_get('ting_search_number_of_facets', 25);
+
+ // Extend query with selected facets.
+ if (isset($conditions['facets']) && $conditions['facets'] != NULL) {
+ $facets = $conditions['facets'];
+ foreach ($facets as $facet) {
+ $facet = explode(':', $facet, 2);
+ if ($facet[0]) {
+ $facet_array[] = $facet[0] . '="' . rawurldecode($facet[1]) . '"';
+ }
}
+
+ $query .= ' AND ' . implode(' AND ', $facet_array);
}
- $query .= ' AND ' . implode(' AND ', $facetArray);
- }
- try {
- $page = pager_find_page();
+ $search_result = NULL;
+ try {
+ $page = pager_find_page();
- $resultsPerPage = variable_get('ting_search_results_per_page', 10);
- if (!empty($conditions['size'])) {
- $resultsPerPage = $conditions['size'];
- }
+ // Set results per page.
+ $results_per_page = variable_get('ting_search_results_per_page', 10);
+ if (!empty($conditions['size'])) {
+ $results_per_page = $conditions['size'];
+ }
- if (!empty($conditions['sort'])) {
- $options['sort'] = $conditions['sort'];
+ // Set sort order.
+ if (!empty($conditions['sort'])) {
+ $options['sort'] = $conditions['sort'];
+ }
+
+ module_load_include('client.inc', 'ting');
+ $search_result = ting_do_search($query, $page + 1, $results_per_page, $options);
+ if (isset($search_result->collections)) {
+ $search_result->search_key = $keys;
+
+ // So we got the total amount of results, but the joker here is that
+ // we have no clue how many collections we got.
+ // Rounded up, this will display 'one more page' if $search-result->more
+ // is true.
+ $total_results = ($page + 1) * $results_per_page + ($search_result->more ? 1 : 0);
+
+ pager_default_initialize($total_results, $results_per_page);
+
+ foreach ($search_result->collections as &$collection) {
+ $build = ting_collection_view($collection, 'teaser');
+ $uri = entity_uri('ting_collection', $collection);
+ $results[] = array(
+ 'link' => url($uri['path'], $uri['options']),
+ 'type' => '',
+ 'title' => $collection->title,
+ 'user' => '',
+ 'date' => '',
+ 'snippet' => drupal_render($build),
+ );
+ }
+ }
+ }
+ catch (TingClientException $e) {
+ watchdog_exception('ting_search', $e);
+ $results = array();
}
- $searchResult = ting_do_search($query, $page + 1, $resultsPerPage, $options);
- if (isset($searchResult->collections)) {
- $searchResult->search_key = $keys;
-
- // TODO: caching highes total_result know value of specific search
- // at the moment we only know if there is one more page
- $total_results = ($page + 1) * $resultsPerPage + ($searchResult->more ? 1 : 0);
-
- pager_default_initialize($total_results, $resultsPerPage);
-
- foreach ($searchResult->collections as &$collection) {
- $build = ting_collection_view($collection, 'teaser');
- $uri = entity_uri('ting_collection', $collection);
- $results[] = array(
- 'link' => url($uri['path'], $uri['options']),
- 'type' => '',
- 'title' => $collection->title,
- 'user' => '',
- 'date' => '',
- 'snippet' => drupal_render($build),
- );
+ // Save search result for usage by facet modules etc.
+ $ting_search_results = &drupal_static('ting_search_results');
+ $ting_search_results = $search_result;
+
+ // Add support for facet api.
+ if (module_exists('ding_facets')) {
+ // @todo ITK Aarhus finish implementation of facet api to use a standard
+ // facet module, that allows usage of modules from D.O. to improved facet
+ // usage.
+ $adapter = facetapi_adapter_load('ding_facets');
+ if ($adapter) {
+ $adapter->addActiveFilters($query);
}
}
}
- catch (TingClientException $e) {
- // TODO: Log the error.
- $results = array();
- }
-
- drupal_static('ting_search_results', $searchResult);
return $results;
}
@@ -389,7 +500,7 @@ function ting_search_search_page($results) {
}
/**
- * Theme a pager
+ * Theme a pager.
*/
function theme_ting_search_pager($variables) {
$tags = $variables['tags'];
@@ -402,15 +513,14 @@ function theme_ting_search_pager($variables) {
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
- // current is the page we are currently paged to
+ // Current is the page we are currently paged to.
$pager_current = $pager_page_array[$element] + 1;
- // first is the first page listed by this pager piece (re quantity)
+ // First is the first page listed by this pager piece (re quantity).
$pager_first = $pager_current - $pager_middle + 1;
- // last is the last page listed by this pager piece (re quantity)
+ // Last is the last page listed by this pager piece (re quantity).
$pager_last = $pager_current + $quantity - $pager_middle;
- // max is the maximum page number
+ // Max is the maximum page number.
$pager_max = $pager_total[$element];
- // End of marker calculations.
// Prepare for generation loop.
$i = $pager_first;
@@ -424,26 +534,43 @@ function theme_ting_search_pager($variables) {
$pager_last = $pager_last + (1 - $i);
$i = 1;
}
- // End of generation loop preparation.
- $li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_previous = theme('pager_previous', array(
+ 'text' => isset($tags[1]) ? $tags[1] : t('‹ previous'),
+ 'element' => $element,
+ 'interval' => 1,
+ 'parameters' => $parameters,
+ ));
if (empty($li_previous)) {
$li_previous = " ";
}
- $li_first = theme('pager_first', array('text' => (isset($tags[0]) ? $tags[0] : t('« first')), 'element' => $element, 'parameters' => $parameters));
+ $li_first = theme('pager_first', array(
+ 'text' => isset($tags[0]) ? $tags[0] : t('« first'),
+ 'element' => $element,
+ 'parameters' => $parameters,
+ ));
if (empty($li_first)) {
$li_first = " ";
}
- $li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_next = theme('pager_next', array(
+ 'text' => isset($tags[3]) ? $tags[3] : t('next ›'),
+ 'element' => $element,
+ 'interval' => 1,
+ 'parameters' => $parameters,
+ ));
if (empty($li_next)) {
$li_next = " ";
}
- $li_last = theme('pager_last', array('text' => (isset($tags[4]) ? $tags[4] : t('last »')), 'element' => $element, 'parameters' => $parameters));
+ $li_last = theme('pager_last', array(
+ 'text' => isset($tags[4]) ? $tags[4] : t('last »'),
+ 'element' => $element,
+ 'parameters' => $parameters,
+ ));
if (empty($li_last)) {
$li_last = " ";
@@ -475,7 +602,12 @@ function theme_ting_search_pager($variables) {
if ($i < $pager_current) {
$items[] = array(
'class' => array('pager-item'),
- 'data' => theme('pager_previous', array('text' => $i, 'element' => $element, 'interval' => ($pager_current - $i), 'parameters' => $parameters)),
+ 'data' => theme('pager_previous', array(
+ 'text' => $i,
+ 'element' => $element,
+ 'interval' => ($pager_current - $i),
+ 'parameters' => $parameters,
+ )),
);
}
if ($i == $pager_current) {
@@ -487,7 +619,12 @@ function theme_ting_search_pager($variables) {
if ($i > $pager_current) {
$items[] = array(
'class' => array('pager-item'),
- 'data' => theme('pager_next', array('text' => $i, 'element' => $element, 'interval' => ($i - $pager_current), 'parameters' => $parameters)),
+ 'data' => theme('pager_next', array(
+ 'text' => $i,
+ 'element' => $element,
+ 'interval' => ($i - $pager_current),
+ 'parameters' => $parameters,
+ )),
);
}
}
@@ -515,7 +652,13 @@ function theme_ting_search_pager($variables) {
'data' => $li_last,
);
}
- return theme('item_list', array('items' => $items, 'type' => 'ul', 'attributes' => array('class' => array('pager'))));
+ return theme('item_list', array(
+ 'items' => $items,
+ 'type' => 'ul',
+ 'attributes' => array(
+ 'class' => array('pager'),
+ ),
+ ));
}
}
@@ -526,32 +669,36 @@ function theme_ting_search_mini_pager($variables) {
$tags = $variables['tags'];
$element = $variables['element'];
$parameters = $variables['parameters'];
- $quantity = $variables['quantity'];
- global $pager_page_array, $pager_total;
-
- // Calculate various markers within this pager piece:
- // Middle is used to "center" pages around the current page.
- $pager_middle = ceil($quantity / 2);
- // current is the page we are currently paged to
- $pager_current = $pager_page_array[$element] + 1;
- // max is the maximum page number
- $pager_max = $pager_total[$element];
- // End of marker calculations.
+ global $pager_total;
-
- $li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_previous = theme('pager_previous', array(
+ 'text' => isset($tags[1]) ? $tags[1] : t('‹ previous'),
+ 'element' => $element,
+ 'interval' => 1,
+ 'parameters' => $parameters,
+ ));
if (empty($li_previous)) {
$li_previous = " ";
}
- $li_first = theme('pager_first', array('text' => (isset($tags[0]) ? $tags[0] : t('« first')), 'element' => $element, 'parameters' => $parameters));
+ $li_first = theme('pager_first', array(
+ 'text' => isset($tags[0]) ? $tags[0] : t('« first'),
+ 'element' => $element,
+ 'parameters' => $parameters,
+ ));
if (empty($li_first)) {
$li_first = " ";
}
- $li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
+ $li_next = theme('pager_next', array(
+ 'text' => isset($tags[3]) ? $tags[3] : t('next ›'),
+ 'element' => $element,
+ 'interval' => 1,
+ 'parameters' => $parameters,
+ ));
+
if (empty($li_next)) {
$li_next = " ";
}
@@ -571,7 +718,13 @@ function theme_ting_search_mini_pager($variables) {
'class' => array('pager-next'),
'data' => $li_next,
);
- return theme('item_list', array('items' => $items, 'type' => 'ul', 'attributes' => array('class' => array('pager'))));
+ return theme('item_list', array(
+ 'items' => $items,
+ 'type' => 'ul',
+ 'attributes' => array(
+ 'class' => array('pager'),
+ ),
+ ));
}
}
@@ -580,19 +733,16 @@ function theme_ting_search_mini_pager($variables) {
* Implements hook_block_info().
*/
function ting_search_block_info() {
- $blocks['sort-form'] = array(
+ return array(
+ 'sort_form' => array(
'info' => t('Ting search "sort by" form'),
'cache' => DRUPAL_CACHE_PER_PAGE,
- );
- $blocks['records-per-page'] = array(
- 'info' => t('Ting search "records per page"'),
- 'cache' => DRUPAL_CACHE_PER_PAGE,
- );
- $blocks['search-display-extended-query'] = array(
+ ),
+ 'search_display_extended_query' => array(
'info' => t('Ting search extended query display'),
'cache' => DRUPAL_CACHE_PER_PAGE,
- );
- return $blocks;
+ ),
+ );
}
/**
@@ -600,23 +750,22 @@ function ting_search_block_info() {
*/
function ting_search_block_view($delta = '') {
$block = array();
+
switch ($delta) {
- case 'sort-form':
- drupal_add_css(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.css');
- drupal_add_js(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.js');
+ case 'sort_form':
+ drupal_add_js(drupal_get_path('module', 'ting_search') . '/js/ting_search_extendform.js');
$block['subject'] = t('Ting search sort controls');
- $block['content'] = drupal_get_form('ting_search_sort_form');
- break;
- case 'records-per-page':
- drupal_add_css(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.css');
- drupal_add_js(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.js');
- $block['subject'] = t('Ting search records per page controls');
- $block['content'] = records_per_page_controls_content() ;
+
+ // Only display form if there are any search results.
+ $search_result = drupal_static('ting_search_results');
+ if (isset($search_result->numTotalObjects) && $search_result->numTotalObjects > 0) {
+ $block['content'] = drupal_get_form('ting_search_sort_form');
+ }
break;
- case 'search-display-extended-query':
- drupal_add_css(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.css');
- drupal_add_js(drupal_get_path('module', 'ting_search') . '/ting_search_extendform.js');
- $block['content'] = theme('ting_search_display_extended_query', array('query_label'=>t('Your query:'),'query_string'=>NULL));
+
+ case 'search_display_extended_query':
+ drupal_add_js(drupal_get_path('module', 'ting_search') . '/js/ting_search_extendform.js');
+ $block['content'] = theme('ting_search_display_extended_query', array('query_label' => t('Your query:'), 'query_string' => NULL));
break;
}
return $block;
@@ -628,36 +777,53 @@ function search_extend_content() {
}
/**
- * Create form for sorting search result
+ * Create form for sorting search result.
*/
function ting_search_sort_form($form_state) {
+ $form = array();
+
$form['sort'] = array(
- '#title' => t('Sort by:'),
'#type' => 'select',
- '#default_value' => isset($_GET['sort']) ? check_plain($_GET['sort']) : '',
- '#options' => array(
- '' => t('Ranking'),
- 'title_ascending' => t('Title (Ascending)'),
- 'title_descending' => t('Title (Descending)'),
- 'creator_ascending' => t('Creator (Ascending)'),
- 'creator_descending' => t('Creator (Descending)'),
- 'date_ascending' => t('Date (Ascending)'),
- 'date_descending' => t('Date (Descending)')
- ),
- '#description' => t('Set sort order for search result'),
+ '#default_value' => isset($_GET['sort']) ? check_plain($_GET['sort']) : variable_get('ting_search_default_sort', ''),
+ '#options' => ting_search_sort_options(),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Sort'),
'#states' => array(
- 'visible' => array(':input[name="op"]' => array('value' => '', ), ),
+ 'visible' => array(':input[name="op"]' => array('value' => '')),
),
);
return $form;
}
/**
- * Process submitted data for sorting order form
+ * Set default sort options.
+ *
+ * @return array
+ * Returns an array of sort options.
+ */
+function ting_search_sort_options() {
+ $options = array(
+ '' => t('Ranking'),
+ 'title_ascending' => t('Title (Ascending)'),
+ 'title_descending' => t('Title (Descending)'),
+ 'creator_ascending' => t('Creator (Ascending)'),
+ 'creator_descending' => t('Creator (Descending)'),
+ 'date_ascending' => t('Date (Ascending)'),
+ 'date_descending' => t('Date (Descending)'),
+ );
+
+ // Add label to the front of the options.
+ foreach ($options as $key => $option) {
+ $options[$key] = t('Sort by: !sort', array('!sort' => $option));
+ }
+
+ return $options;
+}
+
+/**
+ * Process submitted data for sorting order form.
*/
function ting_search_sort_form_submit($form, &$form_state) {
$query = drupal_get_query_parameters();
@@ -666,39 +832,66 @@ function ting_search_sort_form_submit($form, &$form_state) {
$query = array('sort' => $form_state['input']['sort']) + $query;
}
- $form_state['redirect'] = array($_GET['q'], array('query' => $query, ), );
-
+ $form_state['redirect'] = array($_GET['q'], array('query' => $query));
}
/**
- * Create links for changing how many records per page
+ * Create links for changing how many records per page.
+ *
+ * This function uses the static variable "ting_search_results", so if a search
+ * result have not been render yet it will be empty. So you have to ensure that
+ * the search have been executed.
+ *
+ * In panels "render last" option can help in the plugin array.
*/
-function records_per_page_controls_content() {
- $sizes = array('10' => t('10'), '25' => t('25'), '50' => t('50'),);
- $size = array();
- $size['#type'] = 'markup';
- $size['#prefix'] = '' . t('Results on page:');
- $size['#suffix'] = '
';
- $size['#markup'] = '';
-
- foreach ($sizes as $number => $text) {
- $pg = array('page' => 0);
- $sz = array('size' => $number);
- $classes = array();
- $keys = array_keys($sizes);
-
- if (isset($_GET['size']) && $_GET['size'] == $number) {
- $classes += array('selected');
- }
- elseif ((!isset($_GET['size']) ||
- !in_array($_GET['size'], $sizes)) &&
- $number == $keys[0]) {
- $classes += array('selected');
+function ting_search_records_per_page_controls_content() {
+ // Get search results.
+ $search_result = drupal_static('ting_search_results');
+
+ // Use static as panels may call this more than once.
+ $output = &drupal_static(__FUNCTION__, array());
+
+ // Don't show anything if the search result is empty.
+ if (!empty($search_result->collections) && empty($output)) {
+ // Get the default results per page.
+ $def_size = variable_get('ting_search_results_per_page', 10);
+
+ // Set default as the first value.
+ $sizes = array($def_size => $def_size);
+
+ // Increment the default size by 2.5 and 5 to provide the user with three
+ // different options. Defaults to 10, 25, 50 posts per search page.
+ $size = (int) round($def_size * 2.5);
+ $sizes[$size] = $size;
+ $size = (int) round($def_size * 5);
+ $sizes[$size] = $size;
+
+ // Iterate through sizes and build the options.
+ foreach ($sizes as $number => $text) {
+ // Set the current pager page to first page (used in query).
+ $pager_page = array('page' => 0);
+
+ // Find the currently select size.
+ $keys = array_keys($sizes);
+ $selected = FALSE;
+ if (isset($_GET['size']) && $_GET['size'] == $number) {
+ $selected = TRUE;
+ }
+ elseif (!isset($_GET['size']) && $number == $keys[0]) {
+ $selected = TRUE;
+ }
+
+ // Add the result to the output.
+ $output[$text] = array(
+ 'size' => $number,
+ 'text' => $text,
+ 'query' => array('size' => $number) + $pager_page + drupal_get_query_parameters(),
+ 'selected' => $selected,
+ );
}
- $size['#markup'] .= l($text, $_GET['q'], array('query' => $sz + $pg + drupal_get_query_parameters(), 'attributes' => array('class' => $classes, ), ));
- }
- return $size;
+ return $output;
+ }
}
/**
@@ -714,14 +907,14 @@ function ting_search_submit($form, &$form_state) {
unset($_GET['destination']);
}
- $form_id = $form['form_id']['#value']; // 'search_block_form'
+ $form_id = $form['form_id']['#value'];
$keys = $form_state['values'][$form_id];
$fields = array();
$extended_fields = array(
- 'creator' => 'dc.creator',
- 'title' => 'dc.title',
- 'subject' => 'dc.subject',
+ 'creator' => 'term.creator',
+ 'title' => 'term.title',
+ 'subject' => 'term.subject',
);
foreach ($extended_fields as $name => $index) {
@@ -738,15 +931,15 @@ function ting_search_submit($form, &$form_state) {
if (!empty($fields)) {
$q[] = '(' . implode(' AND ', $fields) . ')';
}
- $q = join(' AND ', $q);
+ $q = implode(' AND ', $q);
$s = $form_state['values']['sort'];
- if ( $s != "" ) {
+ if ($s != "") {
$controls['sort'] = $s;
}
$s = $form_state['values']['size'];
- if ( $s != "" ) {
+ if ($s != "") {
$controls['size'] = $s;
}
@@ -776,7 +969,7 @@ function ting_search_submit($form, &$form_state) {
}
if (!empty($search_info['path']) && in_array($search_info['module'], variable_get('search_active_modules', array()))) {
$form_state['redirect'] = FALSE;
- $url = 'search/' . $search_info['path']. '/' . trim($q);
+ $url = 'search/' . $search_info['path'] . '/' . trim($q);
drupal_goto($url, array('query' => $controls));
}
else {
@@ -785,36 +978,9 @@ function ting_search_submit($form, &$form_state) {
}
/**
- * Attempt to quote reserved words in a search query.
- *
- * As proper quoting would require a full CQL parser, we cheat and
- * just work on the part we know is the free text part.
- *
- * Also, we don't mess with uppercase reserved words.
+ * Make sure string is strict cql
*/
function _ting_search_quote($string) {
- if (preg_match('/^(.*?)(AND \(.*|$)/', $string, $rx)) {
- $keys = $rx[1];
- $new_keys = preg_replace_callback('/(?:(".*?(?string_to_cql($string);
}
diff --git a/ting_search.pages.inc b/ting_search.pages.inc
index e45f5f6..5c32297 100644
--- a/ting_search.pages.inc
+++ b/ting_search.pages.inc
@@ -8,9 +8,10 @@ function template_preprocess_ting_search_results(&$variables) {
if (!empty($variables['module'])) {
$variables['module'] = check_plain($variables['module']);
}
+
foreach ($variables['results'] as $result) {
$variables['search_results'] .= theme('search_result', array('result' => $result, 'module' => $variables['module']));
}
- $variables['pager'] = theme('ting_search_mini_pager', array('tags' => NULL));
+ $variables['pager'] = theme('ting_search_pager', array('tags' => NULL));
}
diff --git a/ting_search_extendform.css b/ting_search_extendform.css
deleted file mode 100644
index 07d835f..0000000
--- a/ting_search_extendform.css
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#edit-extend-form label {
- display: inline;
- margin-right: 1em;
-}
-
-.page-search .pane-ting-search-search-display-extended-query .pane-content {
- padding-top: 0.5em;
- padding-bottom: 0em;
- clear: both;
-}
-
-#search-query-display {
- font-size: 0.8em;
- padding-bottom: 0.2em;
- padding-top: 0.2em;
- border-top: 1px solid #E7E7E6;
- clear: both;
-}
-
-span#search-query-label {
- margin-right: 0.5em;
- font-weight: bold;
-}
-