3

In Webform 3.x, I have a "Give me feedback" webform that I embed in various places throughout my site using Panels. This form contains two hidden fields:

Referer / Default value: %server[HTTP_REFERER]

User agent / Default value: %server[HTTP_USER_AGENT]

This is extremely helpful because I can get the details of users' machines without having to ask them as well as get the page the user came from (because the webform is embedded on a number of pages throughout my site with Panels). However, %server\[\] tokens apparently no longer work in Webform 4.x:

Most tokens will be upgraded for you, however some tokens do not have equivalents and no longer work. These include %post, %request, %cookie, and %session. The %get token (which maps to PHP's $_GET variable) has the equivalent token [current-page:query:key].

Is there an alternate way to somehow include the user agent string and referer in a 4.x webform?

  • May I ask you why you wish to upgrade to 4.x? 3.x support will not end soon. I would stay with the 3.x version or use the module "Webform patched". (Just curious as I'm currently doing exactly the same as you stated above - a webform which stores referrer etc.) – Waqar Lim May 16 '13 at 8:00
  • @donschoe I want the integration with the Field API to allow me to prepopulate webform values with (Token module-provided) tokens more easily. I was unable to get this working with 3.x but got it working in 4.x in 5 minutes. – Patrick Kenny May 16 '13 at 8:02
4
+50

This issue is Closed (won't fix) on Drupal.org

If you want them back, you basically need to create a module that implements hook_tokens() and hook_token_info(), as described in the API. I don't think anyone did it already.

Here is how I'd do it:

function yourmodule_token_info() {
  $type = array(
    'name' => t('Server'),
    'description' => t('Tokens related to $_SERVER superglobal.'),
  );
  $tokens = array();
  foreach($_SERVER as $key => $val) { //discard $val now
    $tokens[$key] = array(
      'name' => $key,
      'description' => "\$_SERVER['$key']",
    );
  }
  return array(
    'types' => array('server' => $type),
    'tokens' => array('server' => $tokens),
  );
}

function yourmodule_tokens($type, $tokens, array $data = array(), array $options = array()) {
  if($type == 'server') {
    $replacements = array();
    foreach ($tokens as $name => $original) {
        $replacements[$original] = (string)$_SERVER[$name];
    }
    return $replacements;
  }
}

Of course code above is not production ready, it ignores proper type handling, security issues and so on. It's meant to set you on the right track, but you need to apply your own sanity before deploying it. I take no responsibility for abuse. Read about the reasons it was removed in the first place before you decide to add it back, and be careful to restore only what you really need.

1

For people ending up here via a search engine (like me). If you don't want to open up these globals as tokens and you only want to use this info from these globals as a default value for a webform component, you can also use this code:

/**
 * Allow modules to modify a webform component that is going to be rendered in a form.
 *
 * @param array $element
 *   The display element as returned by _webform_render_component().
 * @param array $component
 *   A Webform component array.
 *
 * @see _webform_render_component()
 */
function hook_webform_component_render_alter(&$element, &$component) {
  if ($component['cid'] == 10) {
    if (!empty($_SERVER['HTTP_REFERER'])) {
      $queryString = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY);
      parse_str($queryString, $queryParams);
      if (!empty($queryParams['persons']) && is_numeric($queryParams['persons'])) {
        $element['#default_value'] = (int) $queryParams['persons'];
      }
    }
  }
}

In my case I wanted to use values as were entered by the visitor in a Views exposed filter. It is an availability search and the visitor can select one of the results to make a booking. The dates were already passed to the webform by the availability calendar module (booking formlet sub module), but the number of persons I had to extract from the query string from the referrer URL which can be done in a secure way with this code.

You can find the cid value in the URL when you are editing the component you want to give a default value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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