You are here

function finder_form_state in Finder 7.2

Same name and namespace in other branches
  1. 6 includes/finder.form.inc \finder_form_state()
  2. 7 includes/finder.form.inc \finder_form_state()

Statically 'get' or 'set' the FAPI form state in a per-finder cache.

When used to 'set' the form state it will also check to see if a redirect is required to go to the results path with arguments. When used to 'get' the form state it will check the static cache for a stored form state, then it will check the session for a form state carried over from another page, and finally it will attempt to build a form state out of the path arguments.

Parameters

$finder: The finder.

$form_state: The Forms API form state (if supplied, will 'set' the form state).

Return value

A copy of the Forms API form state.

5 calls to finder_form_state()
finder::results in includes/finder.inc
Finder results.
finder_ajax in ./finder.module
Ajax callback; get finder ajax output.
finder_form in includes/form.inc
FAPI definition for the finder form.
finder_form_submit in includes/form.inc
Submit function for finder form.
finder_results_ajax in ./finder.module
Menu callback; get finder ajax results output.

File

includes/form.inc, line 371
The finder form.

Code

function finder_form_state($finder, $form_state = NULL) {
  static $finder_form_state = NULL;
  if ($form_state) {

    // we are setting the form_state in a submit.
    // last chance for modules to intefere before potential redirect.
    drupal_alter('finder_form_state', $form_state, $finder);
    $finder_form_state[$finder->name] = $form_state;

    // handle URL stuff.
    if ($finder
      ->setting('url') == 'enabled') {
      $sep = $finder
        ->setting('url_delimiter');
      $empty_symbol = $finder
        ->setting('url_empty') ? $finder
        ->setting('url_empty') : ' ';
      $query = array();
      $keywords = array();
      foreach ($finder->elements as $element) {
        if ($element->element_handler['type'] == 'form' && isset($form_state['values'][$element->id])) {
          $keyword = (array) $form_state['values'][$element->id];
          foreach ($keyword as $k => $v) {

            // Handle forward slashes in input.
            $v = str_replace("/", "%2f%2f", $v);

            // Handle new lines in input.
            $v = str_replace("\r\n", "\n", $v);
            $v = str_replace("\n", urlencode("***BREAK***"), $v);
            if (strpos($v, $sep) !== FALSE) {
              $v = '"' . $v . '"';
            }
            $keyword[$k] = $v ? trim($v) : $empty_symbol;
          }
          $keywords[$element->id] = implode(',', $keyword);
        }
      }

      // Trim the keywords from the end to neaten it up.
      $keywords = array_reverse($keywords);
      $keywords_count = count($keywords);
      foreach ($keywords as $keywords_key => $keywords_value) {

        // If the keyword is empty, and it's not the first keyword.
        $keywords_count--;
        if ($keywords_value == $empty_symbol && $keywords_count) {
          unset($keywords[$keywords_key]);
        }
        else {
          break;
        }
      }
      $keywords = array_reverse($keywords);
      if ($form_state['clicked_button']['#name'] == 'go') {
        $query['go'] = '1';
      }
      $context['sep'] = $sep;
      $context['path'] = $finder->path . '/' . implode('/', $keywords);
      $context['query'] = $query;
      $context['form_state'] = $form_state;
      drupal_alter('finder_form_redirect', $context);
      finder_form_goto($context['sep'], $finder
        ->setting('url_empty'), $context['path'], $context['query']);
    }
  }
  elseif (!isset($finder_form_state[$finder->name])) {
    if ($finder
      ->setting('url') == 'disabled' && isset($_GET['finder'])) {

      // check the session
      $finder_form_state[$finder->name] = $_SESSION['finder'][$_GET['finder']];
    }
    elseif (!isset($_GET['finder']) && strlen($finder->path) < strlen($_GET['q']) && stripos($_GET['q'], $finder->path) === 0) {

      // check the URL
      // Get the seperator for element values - this is usually a comma.
      $sep = $finder
        ->setting('url_delimiter');

      // Get the finder arguments.
      $args = str_replace($finder->path . '/', '', $_GET['q']);

      // Handle new lines from input.
      $args = str_replace("***BREAK***", "\n", $args);

      // Forward slashes were encoded as double forward slashes.  We must temporarily replace those here to prevent the explode() affecting this.
      // Rawurlencode() doesn't work but can be fixed using Apache's AllowEncodedSlashes Directive, but how do you tell people to switch that on?

      //$args = str_replace('//', '[-finder-forward-slash-]', $args);
      $args = str_replace('%2f%2f', '[-finder-forward-slash-]', $args);

      // Double seperators break the $csv_regex below, and I'm not clever enough to fix the regex.
      $args = str_replace($sep . $sep, '[-finder-double-sep-]', $args);

      // Break arguments apart into a string for each element.
      $args = explode('/', $args);
      $form_state['finished'] = TRUE;
      $empty_symbol = !$finder
        ->setting('url_empty') ? $finder
        ->setting('url_empty') : ' ';
      $csv_regex = "/" . $sep . "(?!(?:[^\\\"" . $sep . "]|[^\\\"]" . $sep . "[^\\\"])+\\\")/";
      $args_key = 0;
      foreach ($finder->elements as $key => $element) {
        if ($element->element_handler['type'] == 'form') {
          $keywords = array();
          if (isset($args[$args_key])) {
            $keywords = preg_split($csv_regex, $args[$args_key]);
          }
          $args_key++;
          foreach ($keywords as $k => $v) {
            $v = str_replace('[-finder-double-sep-]', $sep . $sep, $v);
            $v = str_replace('[-finder-forward-slash-]', '/', $v);
            $v = str_replace(urlencode($sep), $sep, trim($v));
            if (trim($v) == trim($empty_symbol)) {
              $v = NULL;
            }
            if (strpos($v, $sep) !== FALSE && $v[0] == '"' && $v[strlen($v) - 1] == '"') {
              $v = substr($v, 1, strlen($v) - 2);
            }
            unset($keywords[$k]);
            if ($v) {
              $keywords[$v] = $v;
            }
          }
          if (count($keywords) === 1) {
            $keywords = current($keywords);
          }
          elseif (!count($keywords)) {
            $keywords = NULL;
          }
          $form_state['values'][$element->id] = $keywords;
        }
      }
      $finder_form_state[$finder->name] = $form_state;
    }
  }
  if (!empty($finder_form_state[$finder->name])) {
    return $finder_form_state[$finder->name];
  }
}