diff -urp views-view-json.tpl.php views-view-json.tpl.php.patched --- views-view-json.tpl.php 2009-11-01 18:53:41.000000000 -0500 +++ views-view-json.tpl.php.patched 2009-11-09 03:38:38.000000000 -0500 @@ -1,5 +1,5 @@ override_path; -function json_simple_render($view, $coder_mode = FALSE) { - define('EXHIBIT_DATE_FORMAT', '%Y-%m-%d %H:%M:%S'); +json_render($view->result, $options); - $eol = ''; - $spaces1 = ''; - $spaces2 = ''; - $spaces4 = ''; - - if ($view->override_path) { - // inside a live preview so use HTML line breaks and space accordingly - $eol = '
'; - $spaces1 = ' '; - $spaces2 = str_repeat(' ', 2); - $spaces4 = str_repeat(' ', 4); - } - - $json = '{' . $spaces1 .'"nodes"'. $spaces1 .':'. $spaces1 .'['. $eol; - - $more_view_results = FALSE; - foreach ($view->result as $node) { - $json .= ($more_view_results ? ','. $eol : '') . $spaces2 .'{'. $eol; - - $more_fields = FALSE; - foreach ($node as $field_label => $field_value) { - $label = trim(views_json_strip_illegal_chars(views_json_encode_special_chars($field_label))); - $value = views_json_encode_special_chars(trim(views_json_is_date($field_value))); - if ((is_null($value)) || ($value == '')) continue; - -// if (preg_match('/\d/', $value)) { -// if (strtotime($value)) { -// $value = gmstrftime(EXHIBIT_DATE_FORMAT, strtotime($value)); -// } -// } - // strip out Profile: from profile fields - $label = str_replace('_value', '', str_replace('profile_values_profile_', '', $label)); +/** + * Render JSON. + * + * The function will directly output a JSON string instead of returning it. + * + * @param $items + * The collection of items to encode into JSON. + * @param $options + * Render options. + */ +function json_render($items, $options) { + $obj = new stdClass(); - if ($view->override_path) { - $value = check_plain($value); - } + // do some preprocessing if necessary - $json .= ($more_fields ? ','. $eol : '') . $spaces4 .'"'. $label .'"'. $spaces1 .':'. $spaces1 .'"'. $value .'"'; + if ($options['format'] === 'exhibit') { + // we'll be rendering MIT Simile/Exhibit JSON - $more_fields = TRUE; + // add required fields + $num_items = count($items); + for ($i = 0; $i < $num_items; ++$i) { + if (!isset($items[$i]->type)) { + $items[$i]->type = (isset($node->type) ? $node->type : 'Item'); + } + if (!isset($items[$i]->label)) { + $items[$i]->label = (isset($node->type) ? $node->title : 'none'); + } } - $json .= $eol . $spaces2 .'}'; - - $more_view_results = TRUE; + $obj->items = $items; } - - $json .= ']'. $spaces1 .'}'; - - if ($view->override_path) { - // we're inside a live preview so pretty-print the JSON - print ''. $json .''; + else { + // we'll be rendering regular JSON + $obj->nodes = $items; } - elseif ($coder_mode) { - // we're in "coder" mode so just output the JSON - print $json; + + // render the output + if ($options['displaying_output']) { + // we're inside a live preview where the JSON is pretty-printed + print ''. _json_preview_render($obj) .''; } else { - // we're in callback mode so switch the content type and stop further processing of the page - drupal_set_header('Content-Type: text/javascript'); - print $json; - module_invoke_all('exit'); - exit; + if (function_exists('json_encode')) { + $json = json_encode($obj); + } + else { + $json = _json_render($obj); + } + + if ($options['using_coder']) { + // we're in "coder" mode + print $json; + } + else { + // we want to send the JSON as a server response so switch the content type + // and stop further processing of the page. + drupal_set_header('Content-Type: application/json'); + print $json; + module_invoke_all('exit'); + exit; + } } } -function json_exhibit_render($view, $coder_mode = FALSE) { - define('EXHIBIT_DATE_FORMAT', '%Y-%m-%d %H:%M:%S'); +/** + * Helper function that builds the JSON. + */ +function _json_render($var) { +// define('EXHIBIT_DATE_FORMAT', '%Y-%m-%d %H:%M:%S'); - $eol = ''; - $spaces1 = ''; - $spaces2 = ''; - $spaces4 = ''; - - if ($view->override_path) { - // inside a live preview so use HTML line breaks and space accordingly - $eol = '
'; - $spaces1 = ' '; - $spaces2 = str_repeat(' ', 2); - $spaces4 = str_repeat(' ', 4); - } - - $json = '{' . $spaces1 .'"items"'. $spaces1 .':'. $spaces1 .'['. $eol; - - $more_view_results = FALSE; - foreach ($view->result as $node) { - $json .= ($more_view_results ? ','. $eol : '') . $spaces2 .'{'. $eol; - $json .= $spaces4 .'"type"'. $spaces1 .':'. $spaces1 .'"'.'##type##'.'",'. $eol; - $json .= $spaces4 .'"label"'. $spaces1 .':'. $spaces1 .'"'.'##label##'.'",'. $eol; - - $more_fields = FALSE; - foreach ($node as $field_label => $field_value) { - $label = trim(views_json_strip_illegal_chars(views_json_encode_special_chars($field_label))); - $value = views_json_encode_special_chars(trim(views_json_is_date($field_value))); - if ((is_null($value)) || ($value == '')) continue; - -// if (preg_match('/\d/', $value)) { -// if (strtotime($value)) { -// $value = gmstrftime(EXHIBIT_DATE_FORMAT, strtotime($value)); + // hack of the elegant drupal_to_js() function + switch (gettype($var)) { + case 'boolean': + // lowercase is necessary! + return $var ? 'true' : 'false'; + case 'integer': + case 'double': + return $var; + case 'resource': + case 'string': +// if (preg_match('/\d/', $var)) { +// if (strtotime($var)) { +// $var = gmstrftime(EXHIBIT_DATE_FORMAT, strtotime($value)); +// } // } -// } - - // strip out Profile: from profile fields - $label = str_replace('_value', '', str_replace('profile_values_profile_', '', $label)); - if ($view->override_path) { - $value = check_plain($value); - } - - if ($label == 'type') { - $json = str_replace('##type##', $value, $json); - } - elseif ($label == 'label') { - $json = str_replace('##label##', $value, $json); + $value = views_json_encode_special_chars(trim(views_json_is_date($var))); +// $value = str_replace(array("\r", "\n", "<", ">", "&"), +// array('\r', '\n', '\x3c', '\x3e', '\x26'), +// addslashes($value)); + return '"'. $value .'"'; + 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[] = _json_render($v); + } + return '['. implode(',', $output) .']'; } - else { - $json .= ($more_fields ? ','. $eol : '') . $spaces4 .'"'. $label .'"'. $spaces1 .':'. $spaces1 .'"'. $value .'"'; + // Otherwise, fall through to convert the array as an object. + case 'object': + $output = array(); + foreach ($var as $k => $v) { + $output[] = trim(views_json_check_label(_json_render(strval($k)))) .':'. _json_render($v); } - } - - if (strpos($json, '##type##') !== FALSE) { - $json = str_replace('##type##', (isset($node->type) ? $node->type : 'Item'), $json); - } - if (strpos($json, '##label##') !== FALSE) { - $json = str_replace('##label##', (isset($node->title) ? $node->title : 'none'), $json); - } + return '{'. implode(',', $output) .'}'; + default: + return 'null'; + } +} - $json .= $eol . $spaces2 .'}'; - $more_view_results = TRUE; - } +/** + * Helper function that builds pretty-printed JSON. + */ +function _json_preview_render($var, $depth = 0) { +// define('EXHIBIT_DATE_FORMAT', '%Y-%m-%d %H:%M:%S'); - $json .= ']'. $spaces1 .'}'; + $base_indent = '  '; + $eol = '
'; + $indent = str_repeat($base_indent, $depth); + + // hack of the elegant drupal_to_js() function + switch (gettype($var)) { + case 'boolean': + // lowercase is necessary! + return $var ? 'true' : 'false'; + case 'integer': + case 'double': + return $var; + case 'resource': + case 'string': +// if (preg_match('/\d/', $var)) { +// if (strtotime($var)) { +// $var = gmstrftime(EXHIBIT_DATE_FORMAT, strtotime($value)); +// } +// } - if ($view->override_path) { - // we're inside a live preview so pretty-print the JSON - print ''. $json .''; - } - elseif ($coder_mode) { - // we're in "coder" mode so just output the JSON - print $json; - } - else { - // we're in callback mode so switch the content type and stop further processing of the page - drupal_set_header('Content-Type: text/javascript'); - print $json; - module_invoke_all('exit'); - exit; + $value = views_json_encode_special_chars(trim(views_json_is_date($var))); +// $value = str_replace(array("\r", "\n", "<", ">", "&"), +// array('\r', '\n', '\x3c', '\x3e', '\x26'), +// addslashes($value)); + return '"'. check_plain($value) .'"'; + 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[] = $indent . $base_indent . _json_preview_render($v, $depth + 1); + } + return '['. (!empty($output) ? $eol . implode(','. $eol, $output) . $eol . $indent : '') .']'; + } + // Otherwise, fall through to convert the array as an object. + case 'object': + $output = array(); + foreach ($var as $k => $v) { + $output[] = $indent . $base_indent . trim(views_json_check_label(_json_preview_render(strval($k)))) .' : '. _json_preview_render($v, $depth + 1); + } + return '{'. (!empty($output) ? $eol . implode(','. $eol, $output) . $eol . $indent : '') .'}'; + default: + return 'null'; } } diff -urp views-view-rdf.tpl.php views-view-rdf.tpl.php.patched --- views-view-rdf.tpl.php 2009-11-01 18:53:41.000000000 -0500 +++ views-view-rdf.tpl.php.patched 2009-10-15 19:10:51.000000000 -0400 @@ -1,5 +1,5 @@ 'radios', '#title' => t('JSON data format'), '#options' => array( - 'simple' => t('Simple'), - 'simple-coder' => t('Simple (Coder)'), - 'exhibit' => t('MIT Simile/Exhibit'), - 'exhibit-coder' => t('MIT Simile/Exhibit (Coder)'), + 'simple' => t('Simple'), + 'exhibit' => t('MIT Simile/Exhibit'), ), '#default_value' => $this->options['format'], ); + $form['using_coder'] = array( + '#type' => 'checkbox', + '#title' => t('Use coder mode'), + '#default_value' => $this->options['using_coder'], + '#description' => t('Not using coder mode means the JSON gets output directly and the server ceases normal page processing. Using coder mode means the server does not cease processing after outputting the JSON. This allows for the Views API to be used with the view without having to prematurely terminate page processing.'), + ); } } diff -urp views_plugin_style_rdf.inc views_plugin_style_rdf.inc.patched --- views_plugin_style_rdf.inc 2009-11-01 18:53:41.000000000 -0500 +++ views_plugin_style_rdf.inc.patched 2009-10-15 19:10:51.000000000 -0400 @@ -1,5 +1,5 @@