4

I have the SOLR search module installed, and have set up a couple of different search pages.

I need to render the form for one of these pages on a separate page. I thought I could just piggy back off the default search_form(), but it doesn't work.

Using this code:

$build['search_form'] = drupal_get_form('search_form', 'directory/search', '', 'apachesolr_search');

The search form is displayed, and has the correct action property. But when the form is submitted, it just redirects to directory/search, without the keys in the URL (which are obviously required for the search).

What am I missing?

4
  • 1
    I tried using code similar to search_view(), but I have the same problem as you have. Using dpm($_POST), I noticed the page callback is called twice; when the page callback is called the second time, $_POST is empty.
    – avpaderno
    Commented Nov 23, 2012 at 15:44
  • Yeah it's a real head-scratcher :) I fancy the Solr module is getting involved early on and redirecting, but I can't find anything to suggest that in the module. The beautiful irony is I had fully faceted search set up in 15 minutes...and I've spent about 2.5 hours so far trying to work this one out!
    – Clive
    Commented Nov 23, 2012 at 15:56
  • I am testing the code with the User module, and I get the same behavior. (I am using the User module just because the search page for nodes is the default one.) I don't think it is because the ApacheSolr module; it must be because the Search module, or the way the page callback is defined.
    – avpaderno
    Commented Nov 23, 2012 at 15:59
  • Thanks @kiamlaluno you're right, I put some debug code directly into the apachesolr_search module and it wasn't getting hit, so it looks like the core search module has a hand in this. I'm not sure where/why but luckily there's a workaround
    – Clive
    Commented Nov 23, 2012 at 16:03

3 Answers 3

1

I have been able to use the search form in a page with a path different from the canonical one, using the following code.

/**
 * Implements hook_menu().
 */
function code_testing_menu() {
  drupal_static_reset('search_get_info');
  $default_info = search_get_default_module_info();

  $items['test/search'] = array(
    'title' => 'User search test', 
    'page callback' => 'drupal_get_form',
    'page arguments' => array('code_testing_user_search_form'), 
    'access callback' => 'search_is_active', 
    'type' => MENU_CALLBACK,
  );

  $items["test/search/%menu_tail"] = array(
    'title' => 'User search test', 
    'load arguments' => array('%map', '%index'), 
    'page callback' => 'drupal_get_form',
    'page arguments' => array('code_testing_user_search_form', 2), 
    'access callback' => '_search_menu_access', 
    'access arguments' => array('user'),
    'type' => MENU_CALLBACK, 
    'weight' => 0,
  );

  return $items;
}

function code_testing_user_search_form($form, &$form_state, $keys = '') {
  $info = FALSE;
  $keys = trim($keys);

  if (!$keys && !empty($_REQUEST['keys'])) {
    $keys = trim($_REQUEST['keys']);
  }

  $active_module_info = search_get_info();

  if (isset($active_module_info['user'])) {
    $info = $active_module_info['user'];
  }

  if (!$info) {
    form_set_error(NULL, t('Search is currently disabled.'), 'error');
    return $form;
  }

  $action = 'test/search';

  $form['#action'] = url($action);
  $form_state['action'] = $action;
  $form['#attributes']['class'][] = 'search-form';

  $form['module'] = array(
    '#type' => 'value',
    '#value' => 'user',
  );

  $form['basic'] = array(
    '#type' => 'container',
    '#attributes' => array('class' => array('container-inline')),
  );

  $form['basic']['keys'] = array(
    '#type' => 'textfield', 
    '#title' => t('Enter your keywords'), 
    '#default_value' => $keys, 
    '#size' => 40, 
    '#maxlength' => 255,
  );

  $form['basic']['processed_keys'] = array(
    '#type' => 'value',
    '#value' => '',
  );

  $form['basic']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );

  if (!empty($form_state['results'])) {
    $form['search_results'] = $form_state['results'];
  }

  return $form;
}

function code_testing_user_search_form_submit($form, &$form_state) {
  $active_module_info = search_get_info();
  $conditions = NULL;
  $keys = $form_state['values']['keys'];

  if (!empty($active_module_info[$form_state['values']['module']])) {
    $info = $active_module_info[$form_state['values']['module']];

    if (isset($info['conditions_callback']) && function_exists($info['conditions_callback'])) {
      $conditions = call_user_func($info['conditions_callback'], $keys);
    }
    if ($keys || !empty($conditions)) {
      $form_state['results'] = search_data($keys, $info['module'], $conditions);
      $form_state['rebuild'] = TRUE;
    }
  }
}

screenshot

I tried writing the page callback (code_testing_user_search_view()) for test/search, and test/search/%menu_tail basing on the search_view() code, but it didn't work. I used dpm($_POST, time()); in code_testing_user_search_view(), and I noticed the function was called twice, after the search form was submitted: In the first invocation, $_POST was populated with the expected values, while in the second invocation $_POST was an empty array. The code I used for code_testing_user_search_view() was slightly different from the code used by search_view() because code_testing_user_search_view() was not getting the name of the module implementing the search hooks as argument.

function code_testing_user_search_view($keys = '') {
  $info = FALSE;
  $redirect = FALSE;
  $keys = trim($keys);

  if (!$keys && !empty($_REQUEST['keys'])) {
    $keys = trim($_REQUEST['keys']);
  }

  $active_module_info = search_get_info();

  if (isset($active_module_info['user'])) {
    $info = $active_module_info['user'];
  }

  $results = array('#markup' => '');

  $conditions =  NULL;

  dpm($_POST);

  if (isset($info['conditions_callback']) && function_exists($info['conditions_callback'])) {
    $conditions = call_user_func($info['conditions_callback'], $keys);
  }

  if ($keys || !empty($conditions)) {
    $results = search_data($keys, $info['module'], $conditions);
  }

  $build['search_form'] = drupal_get_form('search_form', 'test/search', $keys, 'user');
  $build['search_results'] = $results;

  return $build;
}
5

Well I'm not sure what the problem was, but after a bit of further digging into apachesolr_search I've come up with a work around which seems to do the trick:

$search_page = apachesolr_search_page_load('PAGE_ID');

module_load_include('inc', 'apachesolr_search', 'apachesolr_search.pages');
$build['search_form'] = drupal_get_form('apachesolr_search_custom_page_search_form', $search_page);

As kiamlaluno has noted in the comments it doesn't look like it's actually apachesolr_saerch causing this behaviour, but rather the core search module doing...something.

Hopefully this code will save someone the time in the future.

2
  • This worked for us. As an addition - you can use 'core_search' as the PAGE_ID for the default Apache Solr search page.
    – BrianV
    Commented Aug 14, 2013 at 20:12
  • 1
    This worked great, I spent so much time on this already! Because my brain was a bit fried by the time I saw this, it took me a while to figure out the PAGE_ID - this is the ID of the custom search found in /admin/config/search/apachesolr/search-pages
    – ankles
    Commented Aug 11, 2014 at 14:58
0

The Answer By Clive helped a lot. Thank you. I couldn't post this under that answer but it belongs there. A couple additions and a problem I had. If you want to display two forms on the same page to two separate custom pages , I encountered a couple issues. Below is my custom php block where i display search forms to the image library and video library pages.
Problem 1: The forms had the same html id attribute. 2: The second form kept posting to the first search page. I finally fixed that by setting the #action to the forms. It defaulted to the current page the block was on.

Here is the working code. I add some custom classes, tweak the search prompt text,tweak the id , and tweak the action . Works great. Thanks .

<?php 
$search_page = apachesolr_search_page_load('image_library');
module_load_include('inc', 'apachesolr_search', 'apachesolr_search.pages'); 
$form = drupal_get_form('apachesolr_search_custom_page_search_form',$search_page);
$form['#attributes']['class'][] = 'pogoe-libraries-search-box';
$form['#attributes']['class'][] = 'search-message';
$form['basic']['keys']['#title'] = t('Search Images:');
$form['#id'] = "image-search-form";
$form['#action'] = "image-library"; // This defaulted to current page but still worked
print '<div>' . drupal_render($form) . '</div>';
?>

<?php      
$video_search_page = apachesolr_search_page_load('image_library_0');
$vform =drupal_get_form('apachesolr_search_custom_page_search_form',$video_search_page);
$vform['#attributes']['class'][] = 'pogoe-libraries-search-box';
$vform['#attributes']['class'][] = 'search-message';
$vform['#id'] = "video-search-form";
$vform['basic']['keys']['#title'] = t('Search Videos:');
$vform['#action'] = "video-library"; // This defaulted to current page but always took me to the image-library search until I set this to video-library

print '<div>' . drupal_render($vform) . '</div>';
?>

Hope that helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.