function drupal_to_js

You are here

4.7 common.inc drupal_to_js($var)
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()
drupal_get_js in includes/common.inc
Returns a themed presentation of all JavaScript code for the current page.
drupal_json in includes/common.inc
Return data in JSON format.
upload_js in modules/upload/upload.module
Menu-callback for JavaScript-based uploads.
_locale_rebuild_js in includes/locale.inc
(Re-)Creates the JavaScript translation file for a language.

File

includes/common.inc, line 2545
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

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 only in PHP 5.2, Drupal 7 makes use of it

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

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.

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

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

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!