drupal_to_js

5 common.inc drupal_to_js($var)
6 common.inc drupal_to_js($var)

Converts a PHP variable into its Javascript equivalent.

We use HTML-safe strings, i.e. with <, > and & escaped.

4 calls to drupal_to_js()

File

includes/common.inc, line 2532
Common functions that many Drupal modules will need to reference.

Code

function drupal_to_js($var) {
  switch (gettype($var)) {
    case 'boolean':
      return $var ? 'true' : 'false'; // Lowercase necessary!
    case 'integer':
    case 'double':
      return $var;
    case 'resource':
    case 'string':
      return '"' . str_replace(array("\r", "\n", "<", ">", "&"), 
                              array('\r', '\n', '\x3c', '\x3e', '\x26'), 
                              addslashes($var)) . '"';
    case 'array':
      // Arrays in JSON can't be associative. If the array is empty or if it
      // has sequential whole number keys starting with 0, it's not associative
      // so we can go ahead and convert it as an array.
      if (empty($var) || array_keys($var) === range(0, sizeof($var) - 1)) {
        $output = array();
        foreach ($var as $v) {
          $output[] = drupal_to_js($v);
        }
        return '[ ' . implode(', ', $output) . ' ]';
      }
      // Otherwise, fall through to convert the array as an object.
    case 'object':
      $output = array();
      foreach ($var as $k => $v) {
        $output[] = drupal_to_js(strval($k)) . ': ' . drupal_to_js($v);
      }
      return '{ ' . implode(', ', $output) . ' }';
    default:
      return 'null';
  }
}

Comments

Drupal 7

Druplication

Yay Druplication of PHP functions! json_encode() pretty much accomplishes the same thing, but apparently is missing a couple things that we could most definitely easily add to PHP itself.

json_encode() was introduced

json_encode() was introduced only in PHP 5.2, Drupal 7 makes use of it

Patch

I have experienced problems with the D6 implementation of json_encode.

If you have json_encode at your disposal (really, who doesn't?) then this patch might be of interest. Code pulled from D7 drupal_json_encode:

http://pastie.org/2350717

Breaks in jQuery 1.4 AJAX

Note that this function breaks valid json, as it does not properly double escape HTML entities. That will generally not matter until you try to use it with jQuery 1.4. This is fixed in the d7 version.

Ouch

Yes yes, this kept me running in circles for too many hours today. This is really painful.

Found fix while repairing broken block views

I've had to implement the fix below in several sites where views as blocks use ajax paging (with and without panels). It seems to be a stable fix. Should or has an issue been reported? I'm aware that it's dependant on the version of jquery being used (drupal ist still at 1.3.x?) I almost always seem to need to use 1.6 or newer!

http://drupal.org/node/914360#comment-3468550

With jQuery 1.7.2...

I had my AHAH forms break when I upgraded to jQuery 1.7.2. After much reading, the simplest solution I found was to hack the drupal_to_js() function in common.inc.

Yesyes... I know.. evils of hacking core... blahblahblah.. :)

Anyway, it seems the problem is the way drupal_to_js() is encoding the special characters. The new browser-native JSON parsers are more strict than the old jQuery parser. (I was using jQuery 1.3.2 previously.) ...as such, the < script > element I was returning was causing the parser to fail because the "<" and ">" were not being encoded with UTF-8 values. The "< script >" tag was being rendered as "\x3cscript\x3c" - which was "fine" in jQuery 1.3.2, but the browser parsers used by jQuery 1.7.2 require the UTF-8 version: "\u003Cscript\u003E".

So, by changing drupal_to_js() in common.inc from:

case 'string':
      return '"'. str_replace(array("\r", "\n", "<", ">", "&"),
                              array('\r', '\n', '\x3c', '\x3e', '\x26'),
                              addslashes($var)) .'"';

to:

case 'string':
      return '"'. str_replace(array("\r", "\n", "<", ">", "&"),
                              array('\r', '\n', '\u003C', '\u003E', '\x26'),
                              addslashes($var)) .'"';

solved MY problem.

I have NO idea if this fix will have any adverse repercussions, but it worked for me.

EDIT:
This solution ended up only partially working. I ended up using the solution above (replacing the string replace routine). It worked a peach!

Login or register to post comments