Problem/Motivation

The apachesolr module provides a search form block for the default 'Core Search' page. This block cannot be used for additional search pages configured in the 'Pages/Blocks' tab under 'Settings' -> 'Apache Solr search'.

Proposed resolution

A search form block should be provided for every configured search page.

Remaining tasks

The patch in this ticket has been reviewed en tested by several people, so the solution seems ready to go into a stable release.

User interface changes

For every configured search page, a 'Apachesolr search form : [search page name]' block is available in the blocks configuration page.

API changes

None

Data model changes

None

Original report by vistree

Hi, how can I create a search block like drupals core search block?
Or is it possible to use the core to run Solr-quries?

Regards

vistree

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

robertDouglass’s picture

Title: How to create search block » ApacheSolr search block
Category: task » feature

whether you use the core search block or create a new one, you'll want to set the action of the form to be search/apachesolr_search. The action of the core form is search/node. This means you can probably use form_alter to change the action on that form. Or you can create a new search form in the block.

I'm marking this as a feature request and changing the title because I think the module should either ship with its own block, or hijack the existing one.

vistree’s picture

That is great. Thank you for reply.
Where can I change the behaviour? In the template.php?
And can you tell me the correct code for this?

Thank your very much!
vistree

robertDouglass’s picture

Your own custom module is the place where you would implement hook_form_alter. I don't have the exact code for this but you can get a start by reading the API docs: http://api.drupal.org/api/function/hook_form_alter/6

JacobSingh’s picture

Hey Robert,

Didn't you have me and my dad put this functionality in search_config a couple months ago? (where is is now committed).

Best,
Jacob

vistree’s picture

Thank you for the link.
My problem is, that I am no programmer and don't know how to create my own module.
I thought that it would be much more easier to generate my own Solr search block, e.g. by adding a "print ... " in a newly created block.

Is there some more information on how to create such a module or block? Or maybe an already existing example?

Regards

vistree

pahariwalla’s picture

@jacobsingh - I believe you are correct. current dev 5.x-1.4 of search_config module contains that patch (http://drupal.org/project/search_config )

@vistree - after enabling the Search Config module, go to admin/settings/search (Site Configuration | Search Settings). Under "Advanced Search Confuration" you will see "Default Search" which lists of all modules that hook into search. Whichever one you select will cause the Drupal search box to take you to that results tab.

Hope this is what you are looking for.

vistree’s picture

Yes, that is what I am searching for ;-)
Unfortunately I work with Drupal 6 - where is currently no version of the mentioned module above ;-(
Is there an alternative?

Regards
vistree

Anonymous’s picture

Well, not sure if anyone is interested in a followup with this but here's what I did. Dead simple:

Created a block, PHP input filter, with the following code:

<form class="search-form" id="search-form" method="post" accept-charset="UTF-8" action="/path_to_site/search/apachesolr_search/">
<input type="text" class="form-text" value="" id="edit-keys-header" name="keys" maxlength="255"/>
<input id="edit-submit" class="form-submit" type="submit" value="Search" />
</form>

Good to go. Substitute the path to your install in the form action.

Hope that helps.

vistree’s picture

Status: Active » Closed (fixed)

This is great and works well. It is what I was still looking for - thank you!!

Regards

vistree

David Lesieur’s picture

Status: Closed (fixed) » Active

This is still valid as a feature request since it would be useful if the module provided its own search block.

pwolanin’s picture

@David Lesieur - we are planning code to decouple this module from it's dependence on core search, in which case we will certainly provide a separate search block.

coupet’s picture

I think we should suggest an interim solution [Apache Search Block] in module Documentation.

zzolo’s picture

The way the search_theme_form ($search_box variable in the page.tpl.php file) actually goes to the search page is through a redirect in the submission, so we have to add a submission, then redirect it. (May be a more efficient way, but this works)

/**
 * Implementation of hook_form_alter()
 */
function custommodule_form_alter(&$form, $form_state, $form_id) {
  // Search Form (top right), change action to apachesolr
  if ($form_id == 'search_theme_form') {
    // We need to add a submit, because the search form redirects to a specific place
    $form['#submit'][] = 'custommodule_search_submit';
  }
}

/**
 * Implementation of form submit function
 */
function custommodule_search_submit($form, &$form_state) {
  $form_id = $form['form_id']['#value'];
  $form_state['redirect'] = 'search/apachesolr_search/'. trim($form_state['values'][$form_id]);
}
pwolanin’s picture

Status: Active » Closed (duplicate)
Anonymous’s picture

Version: 6.x-1.x-dev » 6.x-1.0-rc2
Status: Closed (duplicate) » Needs review

Code from #13 doesn't work for me. Using Drupal 6.13 and solr 6.x-dev 12th of august.

While custommodule_form_alter() is called, the custommodule_search_submit() is not... So is $form['#submit'][] correct?

P.S. I changed back from duplicate, because it hasnt been committed to the august 12th dev version either. And nowhere is the real solution patched.

robertDouglass’s picture

Version: 6.x-1.0-rc2 » 6.x-2.x-dev
Status: Needs review » Active

I agree that it's not a duplicate, and it's one of the tasks that we need to handle to totally decouple from search.module. But there is no patch, it's an active issue, and it is for 6.2.

Anonymous’s picture

Version: 6.x-2.x-dev » 6.x-1.0-rc2
Status: Active » Needs review

I have "Make Apache Solr Search the default:" set to Enable, which is supposed to redirect the Search Block. But it doesn't work... Only for normal form on /search page

Anonymous’s picture

Version: 6.x-2.x-dev » 6.x-1.0-rc2
Anonymous’s picture

Version: 6.x-1.0-rc2 » 6.x-2.x-dev
Anonymous’s picture

Version: 6.x-1.0-rc2 » 6.x-2.x-dev
Status: Needs review » Active

Solution found! It's an incompatibility with search_config.module! They do this:

function search_config_form_submit($form, &$form_state) {
  $form_id = $form['form_id']['#value'];
  $type = $form['module']['#value'];
  $form_state['redirect'] = 'search/apachesolr_search/'. trim($form_state['values'][$form_id]);
}

Which overrides apache_solr's redirect... I'm just going to deactivate this module. Rather use Solr at all than have this extra.

ducdebreme’s picture

subscribing

janusman’s picture

Status: Active » Closed (fixed)

I think this is solved? Closing out

tbenice’s picture

[edited to add a final sippet at bottom]

I wanted this and started out using the solution in #8, but I wanted to keep the spelling suggestions and retain filters functionality in the block form. I thought I'd post my little solution here.

1) create a block using php with the snippet:

$keys = search_get_keys();
return drupal_get_form('search_form', NULL, $keys, NULL);

2) in your .module file, put a function that recapitulates the apachesolr_search_form_search_form_alter code minus the first conditional statement that selects only forms with ['module']['#value'] == 'apachesolr_search'. Like this:

/**
 * recreate the apachesolr search form alter function for use in creating a search form block
 * we have to do it this way instead of using module_invoke, because module invoke does not pass by reference
 * and the apachesolr function checks for ['module']['#value'] == apachesolr_search.
 * @param $form
 * @param $form_state
 * @return unknown_type
 */
function mymodule_form_alter(&$form, $form_state, $form_id) {
  if (($form_id == 'search_form') && ($form['#action'] == '/search/')) { //select only 'normal' search forms
  $form['#action'] = '/search/apachesolr_search';
  $form['#submit'] = array('apachesolr_search_form_search_submit');
    // No other modification make sense unless a query is active.
    // Note - this means that the query must always be run before
    // calling drupal_get_form('search_form').
    $apachesolr_has_searched = apachesolr_has_searched();

    $queryvalues = array();
    if ($apachesolr_has_searched) {
      $query = apachesolr_current_query();
      $queryvalues = $query->get_url_queryvalues();
    }

    $form['basic']['apachesolr_search']['#tree'] = TRUE;
    $form['basic']['apachesolr_search']['queryvalues'] = array(
      '#type' => 'hidden',
      '#default_value' => serialize($queryvalues),
    );
    $form['basic']['apachesolr_search']['get'] = array(
      '#type' => 'hidden',
      '#default_value' => serialize(array_diff_key($_GET, array('q' => 1, 'page' => 1, 'filters' => 1, 'solrsort' => 1, 'retain-filters' => 1))),
    );
    if ($queryvalues || isset($form_state['post']['apachesolr_search']['retain-filters'])) {
      $form['basic']['apachesolr_search']['retain-filters'] = array(
        '#type' => 'checkbox',
        '#title' => t('Retain current filters'),
        '#default_value' => (int) isset($_GET['retain-filters']),
      );
    }

    if (variable_get('apachesolr_search_spellcheck', TRUE) && $apachesolr_has_searched && ($response = apachesolr_static_response_cache())) {
      // Get spellchecker suggestions into an array.
      if (isset($response->spellcheck->suggestions) && $response->spellcheck->suggestions) {
        $suggestions = get_object_vars($response->spellcheck->suggestions);
        if ($suggestions) {
          // Get the original query and replace words.
          $query = apachesolr_current_query();

          foreach ($suggestions as $word => $value) {
            $replacements[$word] = $value->suggestion[0];
          }
          $new_keywords = strtr($query->get_query_basic(), $replacements);
          
          $query_get = array();          
          if (isset($_GET['retain-filters'])) {
	          $query_get = $queryvalues;
	          $query_get['retain-filters'] = 1;
          }

          // Show only if suggestion is different than current query.
          if ($query->get_query_basic() != $new_keywords) {
            $form['basic']['suggestion'] = array(
              '#prefix' => '<div class="spelling-suggestions">',
              '#suffix' => '</div>',
              '#type' => 'item',
              '#title' => t('Did you mean'),
              '#value' => l($new_keywords, $query->get_path($new_keywords), array('query' => $query_get)),
            );
          }
        }
      }
    }
  }
}

Please note the second line which is added to set the action to search/apachesolr_search.

Also note the added snippet:

          $query_get = array();          
          if (isset($_GET['retain-filters'])) {
	          $query_get = $queryvalues;
	          $query_get['retain-filters'] = 1;
          }

and the line:

              '#value' => l($new_keywords, $query->get_path($new_keywords), array('query' => $query_get)),

which keep the filters and the status of retain-filters=1 when the checkbox is ticked.

Cheers.

maxmmize’s picture

I followed #23but i get sent to: search/node/

Name the module mymodule

twom’s picture

The solution #23 can be simplified if you use

drupal_get_form('search_form', NULL, $keys, 'apachesolr_search');

This will populate ['module']['#value'] with the value apachesolr_search. This means that the default apache solr submit handler will be used!

butler’s picture

Just a note to others who might not get this right away - the simplification suggested in comment #25 refers to step 1. in #23 above. I was poking around in the suggested module code for a bit before I realized this...

esbon’s picture

Hi, I have a similar need which is not redirecting a form the this page: search/apachesolr_search. I recently installed apache solr autocomplete and I would like to just paste this form: search/apachesolr_search on block. Can someone please help deploy this?

esbon’s picture

Post #11 is very good news, do we know when this will happen? Having a an ApacheSolr search block would be the answer to my prayers!

tbenice’s picture

2x to #28. Also, I'd love to see a search block that can limit search to contexts and return results to any arbitrary url. I'm thinking right now of a block for og search that returns results from within a group context to the group page/search. Is that sort of flexibility feasible?

pixelsweatshop’s picture

sub

cafuego’s picture

Status: Closed (fixed) » Needs work

So um, will there be a 6.x-2.x release ever? Or at the very least a release of a 6.x-2.x-beta module?

As it stands, this is a problem with 6.x-1.x and there are no other releases available unless you expect people to fetch them using git. In which case I don't think you'll get many testers.

Nick_vh’s picture

cafuego - The 6.2 will be phased out. We are stabilizing the D7 version first so we can backport all of the functionalities for D7 to D6 version. This will be 6.x-3.x release and will be started in this month and hopefully it will see it's completion soon.

cafuego’s picture

Ok. I should note btw that in 6.x-2.x-beta5 the search block doesn't seem to be using solr, but instead still defaults to the core node search. I've added a submit redirect in a custom module to work around that for the moment.

Nick_vh’s picture

Version: 6.x-2.x-dev » 6.x-1.x-dev

The 6.x-2.x version has been deprecated. Moving this to 6.x-1.x-dev

Nick_vh’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev

Not sure if this is already resolved in the 7.x-1.x branch before backporting this to 6

naeluh’s picture

Has this been back ported to 6x yet ?

ryan.gibson’s picture

So this stalled out.

vonFrakas’s picture

drunken monkey's excellent Search API Pages module provides a search form block (once you configure a search page):
drupal.org/project/search_api_page

I found this module while watching his screencast here: https://vimeo.com/15556855

These links can also be found on the Search API project page.

thePanz’s picture

Issue summary: View changes

There is an (outdated) module here: https://drupal.org/sandbox/incrn8/1315802
I am working at porting it to latest D7 release of ApacheSorl.

Or it is better to work for an integrated solution instead of a separated module?

drikc’s picture

Status: Needs work » Needs review
FileSize
1.49 KB

The attached patch add a search form block for each existing search page.

drikc’s picture

This patch fix the #40 (an issue with the keys selection in item menu).

thePanz’s picture

I created this sandbox project: https://drupal.org/sandbox/thepanz/2239871 please stay tuned few days for first code commit.

drikc’s picture

@thePanz, did you tried the patch in #42? Despite it didn't involve much codes I've packed this also as a sandbox module as I didn't want to patch apachesolr for a project.

thePanz’s picture

@drikc: I didn't test your patch, no time to test it right now

Here: https://drupal.org/sandbox/thepanz/2239871 you can find my module with latest updates, it allow multiple page-blocks to work together, and (with a patch) to correctly integrate with ApacheSolr Autocomplete module.
We should join our forces to provide a common solution for this issue :)

Regards

ps: my module also includes CTools-Exportables settings

asb’s picture

@thePanz: Do I understand it correctly, that your sandbox module (#2239871) is for D7 only and the other sandbox module (#1315802) from 2011 was for D6, but is even two years older than the current recommended release for 'apachesolr' (6.x-1.8 from 2013-Apr-11, which is about one year old)?

So basically there is nothing available for Drupal 6/Pressflow that provides the requested functionality and works out of the box? (I'm asking because I'm struggling to get Apachesolr integrated into Drupal; 6.x-1.8 seems not to integrate much anywhere).

cgmonroe’s picture

Tried the patch in #41 and it would not display the search form on all pages. This was because the More Like This code will run even if the block delta is for the search form.

The fix for this was to move the hook_block_view code above the MLT code and wrap it in a test for search_form_* delta requests.

Here is an updated patch for this.

Koen.Pasman’s picture

Amazing how a topic of 6 years old can still be relevant :)
Anyway, I needed per ApacheSolr search a block, and the patch in #46 does this wonderfully well, thanks a bunch!

Nitebreed’s picture

Status: Needs review » Reviewed & tested by the community

Patch does the job!

janusman’s picture

Title: ApacheSolr search block » Have a search block per each search page

Re-phrasing title. NOW I get it :)

vistree’s picture

This is great. Patch solves my need!

thePanz’s picture

What about integrating the module https://www.drupal.org/sandbox/thepanz/2239871 with your patch (it includes also CTools exportables integration) :)

ckng’s picture

Tested #46 working.

jsst’s picture

Issue summary: View changes

I too can confirm patch #46 is legit! I've updated the issue summary to reflect the current situation.

jsst’s picture

Title: Have a search block per each search page » Have a search block for each search page
jos_s’s picture

Patch #46 indeed gives me search boxes for each search page, but I experience some issues:

  1. When I go to administer blocks I get an error message, and the list of blocks is not displayed. I can solve this by increasing the "delta" field in the "blocks" table from varchar(32) to varchar(64).
  2. When configure the block, I get an error message when I try to change and save the roles that have access to the block.
  3. All the options for related content appear also appear when you configure the block. They have function there.

The standard search block is not affected by this.

arbel’s picture

I have the same issues as Jos_s, getting error messages when trying to access blocks page.

nixar’s picture

Same as #55 (I didn't try the suggested solution of changing the table structure)

tlor24’s picture

This works great but if you need to have multiple search blocks on the main navigation, you will run into the issue of both search form using the same search path.

In our case, we had the default search form up in the header, one apachesolr search block form in one dropdown menu, and another apachesolr search block form in another dropdown menu. In this case, there are three search form all searching in differen solr environment but somehow uses the same search path even with the solr environment setup correctly in the solr page config.

Hopefully this will save some headaches for others.

Here is an updated code from patch 46.

// Search form cases
  elseif ( 0 === strpos($delta, 'search_form_') ) {
    foreach (apachesolr_search_load_all_search_pages() as $page_id => $search_page) {
      if ($delta === 'search_form_' . $page_id) {
        $search_page = apachesolr_search_page_load($page_id);
        $menu_item = menu_get_item();

        if ($menu_item['page_callback'] === 'apachesolr_search_custom_page') {
          if (strpos($menu_item['path'], $search_page['search_path']) !== false) {
            $parts = explode('/', $search_page['search_path']);
            $keys_pos = count($parts);
            $keys = rawurldecode($menu_item['page_arguments'][$keys_pos]);
          }
          // Empty the $keys if the search path from menu_get_item() does not
          // match that of the search form search path.
          else {
            $keys = '';
          }
        }
        else {
          $keys = '';
          module_load_include('pages.inc', 'apachesolr_search');
        }

        $block = array(
          'subject' => t($search_page['page_title']),
          'content' => drupal_get_form('apachesolr_search_custom_page_search_form', $search_page, $keys),
        );

        /**
         * To prevent multiple search form on a single page from having the same
         * search path.
         *
         * If the search path from menu_get_item() does not match that of the
         * search form search path, then set the #attached JS empty.
         */
        if (strpos($menu_item['path'], $search_page['search_path']) === false) {
          $block['content']['#action'] = '/' . $search_page['search_path'] . '/';
          $block['content']['#attached']['js'] = '';
        }

        return $block;
      }
    }
  }
BlackIris’s picture

Just a heads up, plugged in this patch to our site and immediately ran into this error:

PDOException: SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'delta' at row 1: INSERT INTO {block} (module, delta, theme, status, weight, region, pages, cache) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7); Array ( [:db_insert_placeholder_0] => apachesolr_search [:db_insert_placeholder_1] => search_form_taxonomy_search_designs_only [:db_insert_placeholder_2] => pixel_minimal [:db_insert_placeholder_3] => 0 [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => -1 [:db_insert_placeholder_6] => [:db_insert_placeholder_7] => -1 ) in drupal_write_record() (line 7361 of /srv/www/pixelscrapper.com/public_html/includes/common.inc).

The problem was we had some long page names, and the $delta ended up being too long, causing the block page to be inaccessible. Upon changing the page names worked fine. Something probably needs to be entered into the code to check for this.

JordanMagnuson’s picture

Status: Reviewed & tested by the community » Needs work

I also ran into the issue in #59. We need to check strlen($delta) and abbreviate in some way if too long (could chop $delta down to size and add number at end if necessary to prevent conflicts in $delta name).

herved’s picture

Hello everyone,

I noticed that the $keys passed to apachesolr_search_custom_page_search_form() are not retrieved successfully.
It should be offset by -1 if I'm not mistaken but here is a better approach using apachesolr_has_searched() and apachesolr_current_query().

Issues reported in #58 and #59 are still valid though :\

Greg Boggs’s picture

This patch combines #58 and #61 to work with the latest dev release of apachesolr. I did not experience problems with my delta being too long, so I didn't attempt to add code for that. We should follow up with a different issue about maximum page name length.