finder_id); if (is_array($finder_form_state)) { $form_state = array_merge($form_state, $finder_form_state); } finder_invoke_finderapi($finder, 'finder_form', $form, $form_state); $form['finder_id'] = array ( '#type' => 'value', '#value' => $finder->finder_id, ); $form['#action'] = url($finder->path); $form['finder_form'] = array( '#weight' => 0, '#prefix' => '
', '#suffix' => '
', ); $form['finder_form']['#prefix'] .= $finder->settings['form']['prefix'] ? '
'. $finder->settings['form']['prefix'] .'
' : ''; $max_weight = 0; foreach ((array)$finder->elements as $element) { $max_weight = max($max_weight, $element->weight); if (isset($form_state['values'][$element->finder_element_id])) { $element_default = $form_state['values'][$element->finder_element_id]; } else { $element_default = $element->settings['form']['default_value']; } $form['finder_form'][$element->finder_element_id] = array( '#title' => $element->title, '#weight' => $element->weight, '#description' => $element->description, '#prefix' => $element->settings['form']['prefix'], '#suffix' => $element->settings['form']['suffix'], '#default_value' => $element_default, '#required' => $element->settings['form']['required'], '#executes_submit_callback' => TRUE, ); $module = &$element->element_handler['#module']; // module_invoke doesn't seem to handle references. $handler_function = $module .'_finder_element'; if (function_exists($handler_function)) { $handler_function($element, $form['finder_form'][$element->finder_element_id]); } } if ($finder->settings['advanced']['submission']) { $form['finder_form']['submit'] = array( '#type' => 'submit', '#name' => 'find', '#value' => $finder->settings['form']['button_text'], '#weight' => $max_weight + 1000, ); if ($finder->settings['advanced']['ahah']) { $form['finder_form']['submit']['#ahah'] = array( 'path' => 'finder/finder_ahah/'. $finder->finder_id, 'wrapper' => $finder->finder_view_build_id, 'method' => 'replace', 'effect' => $finder->settings['advanced']['ahah_effect'], ); } if ($finder->settings['advanced']['goto'] == 'go') { $form['finder_form']['submit']['#prefix'] = '
'; $form['finder_form']['go'] = array( '#type' => 'submit', '#name' => 'go', '#value' => $finder->settings['form']['go_text'], '#weight' => $max_weight + 1010, '#suffix' => '
', ); } } $form['finder_form']['#suffix'] = ($finder->settings['form']['suffix'] ? '
'. $finder->settings['form']['suffix'] .'
' : '') . $form['finder_form']['#suffix']; $form['#submit'] = array( 'finder_form_submit', ); return $form; } /** * Submit function for finder form. * * Adds some needed data to $form_state and calls finder_form_state(). * * @see finder_form() */ function finder_form_submit($form, &$form_state) { $finder_id = $form_state['values']['finder_id']; $finder = finder_load($finder_id); $form_state['storage']['finder'] = $finder; $form_state['storage']['values'] = $form_state['values']; $form_state['storage']['finished'] = TRUE; finder_form_state($finder->finder_id, $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. * * @param $finder_id * The finder's ID. * @param $form_state * The Forms API form state (if supplied, will 'set' the form state). * @return * A copy of the Forms API form state. */ function finder_form_state($finder_id, $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_id); $finder_form_state[$finder_id] = $form_state; // handle URL stuff. $finder = finder_load($finder_id); if (!$finder->settings['advanced']['hide_args']) { $sep = &$finder->settings['advanced']['arg_sep']; $query = array(); foreach ($finder->elements as $element) { $keyword = array(); //if (!is_null($form_state['values'][$element->finder_element_id])) { // this was intefering [#593060] $keyword = (array)$form_state['values'][$element->finder_element_id]; foreach($keyword as $k => $v) { if (strpos($v, $sep) !== FALSE) { $v = '"'. $v .'"'; } $keyword[$k] = $v ? trim($v) : ' '; } //} $keywords[$element->finder_element_id] = implode(',', $keyword); } if (!$form_state['storage']['finished']) { $query['finished'] = '0'; } if ($form_state['clicked_button']['#name'] == 'go' && $form_state['storage']['finished']) { $query['go'] = '1'; } finder_form_goto($sep, $finder->path .'/'. implode('/', $keywords), $query); } } elseif (!isset($finder_form_state[$finder_id])) { $finder = finder_load($finder_id); if ($finder->settings['advanced']['hide_args'] && isset($_GET['finder'])) { // check the session $finder_form_state[$finder_id] = $_SESSION['finder'][$_GET['finder']]; } elseif (!isset($_GET['finder']) && strlen($finder->path) < strlen($_GET['q']) && stripos($_GET['q'], $finder->path) === 0) { // check the URL $args = explode('/', str_replace($finder->path .'/', '', $_GET['q'])); $form_state['storage']['finished'] = TRUE; $sep = &$finder->settings['advanced']['arg_sep']; $csv_regex = "/". $sep ."(?!(?:[^\\\"". $sep ."]|[^\\\"]". $sep ."[^\\\"])+\\\")/"; foreach ($finder->elements as $key => $element) { $keywords = preg_split($csv_regex, $args[$key]); foreach ($keywords as $k => $v) { $v = str_replace(urlencode($sep), $sep, trim($v)); 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->finder_element_id] = $keywords; } $finder_form_state[$finder_id] = $form_state; } } return $finder_form_state[$finder_id]; } /** * Redirect from a finder form. * * The difference between this and drupal_goto() is that this undoes the * encoding of the arguments seperator, as such encoding inteferes with finder. * * @param $sep * The arguments seperator string. * @param $path * A Drupal path or a full URL. * @param $query * A query string component, if any. * @param $fragment * A destination fragment identifier (named anchor). * @param $http_response_code * Valid values for an actual "goto" as per RFC 2616 section 10.3 are: * - 301 Moved Permanently (the recommended value for most redirects) * - 302 Found (default in Drupal and PHP, sometimes used for spamming search * engines) * - 303 See Other * - 304 Not Modified * - 305 Use Proxy * - 307 Temporary Redirect (alternative to "503 Site Down for Maintenance") * Note: Other values are defined by RFC 2616, but are rarely used and poorly * supported. * @see drupal_goto() */ function finder_form_goto($sep, $path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) { if (isset($_REQUEST['destination'])) { extract(parse_url(urldecode($_REQUEST['destination']))); } else if (isset($_REQUEST['edit']['destination'])) { extract(parse_url(urldecode($_REQUEST['edit']['destination']))); } $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE)); // custom changes - undo separator encoding $url = str_replace(urlencode($sep), $sep, $url); // Remove newlines from the URL to avoid header injection attacks. $url = str_replace(array("\n", "\r"), '', $url); // Allow modules to react to the end of the page request before redirecting. // We do not want this while running update.php. if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') { module_invoke_all('exit', $url); } // Even though session_write_close() is registered as a shutdown function, we // need all session data written to the database before redirecting. session_write_close(); header('Location: '. $url, TRUE, $http_response_code); // The "Location" header sends a redirect status code to the HTTP daemon. In // some cases this can be wrong, so we make sure none of the code below the // drupal_goto() call gets executed upon redirection. exit(); }