Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Make usage of zend-json fully optional #113

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"zendframework/zend-di": "^2.6",
"zendframework/zend-filter": "^2.6.1",
"zendframework/zend-inputfilter": "^2.6",
"zendframework/zend-json": "^2.6.1",
"zendframework/zend-log": "^2.7.1",
"zendframework/zend-modulemanager": "^2.7.1",
"zendframework/zend-serializer": "^2.6.1",
Expand All @@ -43,7 +42,7 @@
"zendframework/zend-filter": "Zend\\Filter component",
"zendframework/zend-http": "Zend\\Http component",
"zendframework/zend-inputfilter": "Zend\\Inputfilter component",
"zendframework/zend-json": "Zend\\Json component",
"zendframework/zend-json": "To auto-deserialize JSON body content in AbstractRestfulController extensions, when json_decode is unavailable",
"zendframework/zend-log": "Zend\\Log component",
"zendframework/zend-modulemanager": "Zend\\ModuleManager component",
"zendframework/zend-mvc-console": "zend-mvc-console provides the ability to expose zend-mvc as a console application",
Expand Down
4 changes: 2 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 54 additions & 7 deletions src/Controller/AbstractRestfulController.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,23 @@ abstract class AbstractRestfulController extends AbstractController
protected $identifierName = 'id';

/**
* @var int From Zend\Json\Json
* Flag to pass to json_decode and/or Zend\Json\Json::decode.
*
* The flags in Zend\Json\Json::decode are integers, but when evaluated
* in a boolean context map to the flag passed as the second parameter
* to json_decode(). As such, you can specify either the Zend\Json\Json
* constant or the boolean value. By default, starting in v3, we use
* the boolean value, and cast to integer if using Zend\Json\Json::decode.
*
* Default value is boolean true, meaning JSON should be cast to
* associative arrays (vs objects).
*
* Override the value in an extending class to set the default behavior
* for your class.
*
* @var int|bool
*/
protected $jsonDecodeType = Json::TYPE_ARRAY;
protected $jsonDecodeType = true;

/**
* Map of custom HTTP methods and their handlers
Expand Down Expand Up @@ -444,16 +458,16 @@ public function onDispatch(MvcEvent $e)
*
* @param Request $request
* @return mixed
* @throws Exception\DomainException If a JSON request was made, but no
* method for parsing JSON is available.
*/
public function processPostData(Request $request)
{
if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) {
$data = Json::decode($request->getContent(), $this->jsonDecodeType);
} else {
$data = $request->getPost()->toArray();
return $this->create($this->jsonDecode($request->getContent()));
}

return $this->create($data);
return $this->create($request->getPost()->toArray());
}

/**
Expand Down Expand Up @@ -564,14 +578,16 @@ protected function getIdentifier($routeMatch, $request)
*
* @param mixed $request
* @return object|string|array
* @throws Exception\DomainException If a JSON request was made, but no
* method for parsing JSON is available.
*/
protected function processBodyContent($request)
{
$content = $request->getContent();

// JSON content? decode and return it.
if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) {
return Json::decode($content, $this->jsonDecodeType);
return $this->jsonDecode($request->getContent());
}

parse_str($content, $parsedParams);
Expand All @@ -585,4 +601,35 @@ protected function processBodyContent($request)

return $parsedParams;
}

/**
* Decode a JSON string.
*
* Uses json_decode by default. If that is not available, checks for
* availability of Zend\Json\Json, and uses that if present.
*
* Otherwise, raises an exception.
*
* Marked protected to allow usage from extending classes.
*
* @param string
* @return mixed
* @throws Exception\DomainException if no JSON decoding functionality is
* available.
*/
protected function jsonDecode($string)
{
if (function_exists('json_decode')) {
return json_decode($string, (bool) $this->jsonDecodeType);
}

if (class_exists(Json::class)) {
return Json::decode($string, (int) $this->jsonDecodeType);
}

throw new Exception\DomainException(sprintf(
'Unable to parse JSON request, due to missing ext/json and/or %s',
Json::class
));
}
}