Currently the function _views_json_json_nested only allows to pass in a single nested field name. We should allow multiple field names to be passed into the function. Below is the modified function that allows multiple field names.

/**
 * Encodes the provided nested array into JSON format, preserving the contents
 * of the specified field as-is as a raw, nested JSON value.
 *
 * @param $rows
 *   The nested array to encode into JSON.
 *
 * @param $jsonOptions
 *   The JSON encoder settings bitmask, if the format that would be passed for
 *   $options to PHP's json_encode() function.
 *
 * @param $previewAsHtml
 *   Whether or not the JSON is being previewed in the Views UI interface.
 *
 * @param $rootObjectName
 *   The name of the root value in the array.
 *
 * @param $nestedFieldNames
 *   An array of field names in each row that is to be protected from escaping
 *   because it already contains JSON that should be passed through raw.
 *
 * @return string
 *   Either the JSON encoded string on success; or FALSE on
 *   failure.
 */
function _views_json_json_nested($rows, $jsonOptions, $previewAsHtml, $rootObjectName, $nestedFieldNames) {
  if (isset($rows[$rootObjectName])) {
    /* Pick a random number to include in the pattern, to further reduce the
     * chances of coming across content that just happens to match our
     * placeholder pattern.
     */

    $unescapedItems = array();

    $events =& $rows[$rootObjectName];

    foreach ($nestedFieldNames as $nestedFieldName) {

      $rawFieldPlaceholderPattern =
        sprintf(
          "%s_PLACEHOLDER_%d_",
          $nestedFieldName,
          rand(1, 2000));


      foreach ($events as $index => &$event) {
        if (isset($event[$nestedFieldName])) {
          $placeholderContent = $rawFieldPlaceholderPattern . $index;

          /* JSON wraps the content in quotes, making it a string.
          * For us to nest the JSON as JSON, we need to strip the quotes, so
          * we include them in the key so that strtr() handle the replacement.
          */
          $placeholderKey     = '"' . $placeholderContent . '"';

          $unescapedItems[$placeholderKey]  = trim($event[$nestedFieldName]);
          $event[$nestedFieldName]          = $placeholderContent;
        }
      }
    }

    if ($previewAsHtml) {
      $jsonContent = _views_json_encode_formatted($rows, $jsonOptions);
    }
    else {
      $jsonContent = _views_json_json_encode($rows, $jsonOptions);
    }

    /* Replace the placeholders with the corresponding raw JSON values we saved
     * before we passed the object through json_encode().
     */
    $result = strtr($jsonContent, $unescapedItems);
  }
  else {
    if ($previewAsHtml) {
      $result = _views_json_encode_formatted($rows, $jsonOptions);
    }
    else {
      $result = _views_json_json_encode($rows, $jsonOptions);
    }
  }

  return $result;
}

Comments

wlofgren created an issue. See original summary.

wlofgren’s picture