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

Commit b529b1d

Browse files
committed
Make usage of zend-json fully optional
Adds a new method to `AbstractRestfulController`, `jsonEncode()` which: - checks for presence of `json_encode()`; if present, uses it to decode the provided string. - checks for presence of `Zend\Json\Json`; if present, uses `Zend\Json\Json::decode()` to decode the provided string. - throws an exception if neither is available The above is now used by both `processPostData()` and `processBodyContent()` when parsing JSON. Removed `zend-json` from the `require-dev` section, and updated its description in the `suggest` section.
1 parent 5f2f4cc commit b529b1d

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
"zendframework/zend-di": "^2.6",
2929
"zendframework/zend-filter": "^2.6.1",
3030
"zendframework/zend-inputfilter": "^2.6",
31-
"zendframework/zend-json": "^2.6.1",
3231
"zendframework/zend-log": "^2.7.1",
3332
"zendframework/zend-modulemanager": "^2.7.1",
3433
"zendframework/zend-serializer": "^2.6.1",
@@ -43,7 +42,7 @@
4342
"zendframework/zend-filter": "Zend\\Filter component",
4443
"zendframework/zend-http": "Zend\\Http component",
4544
"zendframework/zend-inputfilter": "Zend\\Inputfilter component",
46-
"zendframework/zend-json": "Zend\\Json component",
45+
"zendframework/zend-json": "To auto-deserialize JSON body content in AbstractRestfulController extensions, when json_decode is unavailable",
4746
"zendframework/zend-log": "Zend\\Log component",
4847
"zendframework/zend-modulemanager": "Zend\\ModuleManager component",
4948
"zendframework/zend-mvc-console": "zend-mvc-console provides the ability to expose zend-mvc as a console application",

composer.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Controller/AbstractRestfulController.php

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,23 @@ abstract class AbstractRestfulController extends AbstractController
4545
protected $identifierName = 'id';
4646

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

5266
/**
5367
* Map of custom HTTP methods and their handlers
@@ -444,16 +458,16 @@ public function onDispatch(MvcEvent $e)
444458
*
445459
* @param Request $request
446460
* @return mixed
461+
* @throws Exception\DomainException If a JSON request was made, but no
462+
* method for parsing JSON is available.
447463
*/
448464
public function processPostData(Request $request)
449465
{
450466
if ($this->requestHasContentType($request, self::CONTENT_TYPE_JSON)) {
451-
$data = Json::decode($request->getContent(), $this->jsonDecodeType);
452-
} else {
453-
$data = $request->getPost()->toArray();
467+
return $this->create($this->jsonDecode($request->getContent()));
454468
}
455469

456-
return $this->create($data);
470+
return $this->create($request->getPost()->toArray());
457471
}
458472

459473
/**
@@ -564,14 +578,16 @@ protected function getIdentifier($routeMatch, $request)
564578
*
565579
* @param mixed $request
566580
* @return object|string|array
581+
* @throws Exception\DomainException If a JSON request was made, but no
582+
* method for parsing JSON is available.
567583
*/
568584
protected function processBodyContent($request)
569585
{
570586
$content = $request->getContent();
571587

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

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

586602
return $parsedParams;
587603
}
604+
605+
/**
606+
* Decode a JSON string.
607+
*
608+
* Uses json_decode by default. If that is not available, checks for
609+
* availability of Zend\Json\Json, and uses that if present.
610+
*
611+
* Otherwise, raises an exception.
612+
*
613+
* Marked protected to allow usage from extending classes.
614+
*
615+
* @param string
616+
* @return mixed
617+
* @throws Exception\DomainException if no JSON decoding functionality is
618+
* available.
619+
*/
620+
protected function jsonDecode($string)
621+
{
622+
if (function_exists('json_decode')) {
623+
return json_decode($string, (bool) $this->jsonDecodeType);
624+
}
625+
626+
if (class_exists(Json::class)) {
627+
return Json::decode($string, (int) $this->jsonDecodeType);
628+
}
629+
630+
throw new Exception\DomainException(sprintf(
631+
'Unable to parse JSON request, due to missing ext/json and/or %s',
632+
Json::class
633+
));
634+
}
588635
}

0 commit comments

Comments
 (0)