ZF-10977: Allow JSON action helper to accept pre-encoded JSON

Description

A very nice method for returning json content is to use the json ActionHelper:


function listAction()
{
  return $this->_helper->json($dataArray);
}

But using this method with data stored in some temporary cache requires the decoding and re-encoding of the information:

 
function listAction()
{
  return $this->_helper->json(json_decode(file_get_contents($cacheFile)));

  //or

  return $this->_helper->json(unserialize(file_get_contents($cacheFile)));
}

It would be faster to just json encode the data in the cache and output them with a simple:

 
  return $this->_helper->json(file_get_contents($cacheFile),array('jsonEncode'=>false));

It is quite easy to implement, as it requires only a couple of lines in Zend_Json::encode():

 
        if (isset($options['jsonEncode']) && false === $options['jsonEncode']) {
            return $valueToEncode;
        }

Comments

I've attached a patch which implements the functionality you are looking for. As {{Zend_Controller_Action_Helper_Json}} doesn't use a configuration array, the usage is slightly different:


return $this->_helper->json(file_get_contents($cacheFile), true, false, true);

Where {{$this->_helper->json}} has the following method signuature:


/**
 * Strategy pattern: call helper as helper broker method
 *
 * Allows encoding JSON. If $sendNow is true, immediately sends JSON
 * response.
 *
 * @param  mixed   $data
 * @param  boolean $sendNow
 * @param  boolean $keepLayouts
 * @param  boolean $dataIsJson Provided data is already JSON
 * @return string|void
 */
public function direct($data, $sendNow = true, $keepLayouts = false, $dataIsJson = false)

The usage is a little clumsy, and I think that this action helper could be restructured to also allow setting configurations in the syntax you use in your example without breaking BC.

Thoughts?

I've reviewed the patch and confirm it operates as intended. Please ensure a matching unit test is included before committing.

Recommend committing to trunk (need to check with Matthew on adding to release branch as it adds to the API). Please ensure a ZF2 git pull request including matching changes is issued for ZF2 before resolving.

The patch works perfectly, but I do agree that the usage could be a little clumsy. If you are worried about that, a way to mantain BC could be to check if $sendNow is an array, and then parse it for the relevant parameters. Could that work?

Upon further review, I missed one thing: The original patch I suggested short-circuits the calling of {{Zend_View_Helper_Json}} entirely, which means that the JSON headers never get set. I've attached an updated patch with unit tests which address this issue by extending the encoding enable/disable flag into {{Zend_View_Helper_Json}} as well. There is also an updated manual page for {{Zend_View_Helper_Json}} which explains how to disable encoding. I did not update the {{Zend_Controller_Action_Helper_Json}} manual page, as it needs a rewrite (see below).

The question of providing an array shortcut via {{$sendNow}} is related to ZF-11826. {{Zend_Controller_Action_Helper_Json}}'s manual page gives incorrect examples which show an array shortcut functionality that doesn't exist in that component. Whether we choose to add that feature, or simply change the manual page, it will be done under that issue #.

Fixed in trunk r24829. No forward-port to ZF2 as it does not have the JSON action helper anymore.