Skip to content

Commit 833913e

Browse files
authored
Json alt (#762)
* Added json middleware * json middleware
1 parent d979256 commit 833913e

File tree

5 files changed

+154
-2
lines changed

5 files changed

+154
-2
lines changed

src/Tqdev/PhpCrudApi/Api.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Tqdev\PhpCrudApi\Middleware\FirewallMiddleware;
2626
use Tqdev\PhpCrudApi\Middleware\IpAddressMiddleware;
2727
use Tqdev\PhpCrudApi\Middleware\JoinLimitsMiddleware;
28+
use Tqdev\PhpCrudApi\Middleware\JsonMiddleware;
2829
use Tqdev\PhpCrudApi\Middleware\JwtAuthMiddleware;
2930
use Tqdev\PhpCrudApi\Middleware\MultiTenancyMiddleware;
3031
use Tqdev\PhpCrudApi\Middleware\PageLimitsMiddleware;
@@ -115,7 +116,10 @@ public function __construct(Config $config)
115116
case 'xml':
116117
new XmlMiddleware($router, $responder, $properties, $reflection);
117118
break;
118-
}
119+
case 'json':
120+
new JsonMiddleware($router, $responder, $properties);
121+
break;
122+
}
119123
}
120124
foreach ($config->getControllers() as $controller) {
121125
switch ($controller) {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
namespace Tqdev\PhpCrudApi\Middleware;
4+
5+
use Psr\Http\Message\ResponseInterface;
6+
use Psr\Http\Message\ServerRequestInterface;
7+
use Psr\Http\Server\RequestHandlerInterface;
8+
use Tqdev\PhpCrudApi\Middleware\Base\Middleware;
9+
use Tqdev\PhpCrudApi\RequestUtils;
10+
use Tqdev\PhpCrudApi\ResponseFactory;
11+
12+
class JsonMiddleware extends Middleware
13+
{
14+
private function convertJsonRequestValue($value) /*: object */
15+
{
16+
if (is_array($value) || is_object($value)) {
17+
$value = json_encode($value,JSON_UNESCAPED_UNICODE);
18+
}
19+
return $value;
20+
}
21+
22+
private function convertJsonRequest($object, array $fieldNames) /*: object */
23+
{
24+
if (is_array($object)) {
25+
foreach ($object as $i => $obj) {
26+
foreach ($obj as $k => $v) {
27+
if (in_array('all', $fieldNames) || in_array($k, $fieldNames)) {
28+
$object[$i]->$k = $this->convertJsonRequestValue($v);
29+
}
30+
}
31+
}
32+
} else if (is_object($object)) {
33+
foreach ($object as $k => $v) {
34+
if (in_array('all', $fieldNames) || in_array($k, $fieldNames)) {
35+
$object->$k = $this->convertJsonRequestValue($v);
36+
}
37+
}
38+
}
39+
return $object;
40+
}
41+
42+
private function convertJsonResponseValue(string $value) /*: object */
43+
{
44+
if (strlen($value) > 0 && in_array($value[0],['[','{'])) {
45+
$parsed = json_decode($value);
46+
if (json_last_error() == JSON_ERROR_NONE) {
47+
$value = $parsed;
48+
}
49+
}
50+
return $value;
51+
}
52+
53+
54+
private function convertJsonResponse($object, array $fieldNames) /*: object */
55+
{
56+
if (is_array($object)) {
57+
foreach ($object as $k => $v) {
58+
$object[$k] = $this->convertJsonResponse($v, $fieldNames);
59+
}
60+
} else if (is_object($object)) {
61+
foreach ($object as $k => $v) {
62+
if (in_array('all', $fieldNames) || in_array($k, $fieldNames)) {
63+
$object->$k = $this->convertJsonResponse($v, $fieldNames);
64+
}
65+
}
66+
} else if (is_string($object)) {
67+
$object = $this->convertJsonResponseValue($object);
68+
}
69+
return $object;
70+
}
71+
72+
public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface
73+
{
74+
$operation = RequestUtils::getOperation($request);
75+
$controllerPath = RequestUtils::getPathSegment($request, 1);
76+
$tableName = RequestUtils::getPathSegment($request, 2);
77+
78+
$controllerPaths = $this->getArrayProperty('controllers', 'all');
79+
$tableNames = $this->getArrayProperty('tables', 'all');
80+
$fieldNames = $this->getArrayProperty('fields', 'all');
81+
if (
82+
(in_array('all', $controllerPaths) || in_array($controllerPath, $controllerPaths)) &&
83+
(in_array('all', $tableNames) || in_array($tableName, $tableNames))
84+
) {
85+
if (in_array($operation, ['create', 'update'])) {
86+
$records = $request->getParsedBody();
87+
$records = $this->convertJsonRequest($records,$fieldNames);
88+
$request = $request->withParsedBody($records);
89+
}
90+
$response = $next->handle($request);
91+
if (in_array($operation, ['read', 'list'])) {
92+
$records = json_decode($response->getBody()->getContents());
93+
$records = $this->convertJsonResponse($records, $fieldNames);
94+
$response = ResponseFactory::fromObject($response->getStatusCode(), $records);
95+
}
96+
} else {
97+
$response = $next->handle($request);
98+
}
99+
return $response;
100+
}
101+
}

tests/config/base.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'username' => 'incorrect_username',
55
'password' => 'incorrect_password',
66
'controllers' => 'records,columns,cache,openapi,geojson,status',
7-
'middlewares' => 'sslRedirect,xml,cors,reconnect,dbAuth,jwtAuth,basicAuth,authorization,sanitation,validation,ipAddress,multiTenancy,pageLimits,joinLimits,customization',
7+
'middlewares' => 'sslRedirect,xml,cors,json,reconnect,dbAuth,jwtAuth,basicAuth,authorization,sanitation,validation,ipAddress,multiTenancy,pageLimits,joinLimits,customization',
88
'dbAuth.mode' => 'optional',
99
'dbAuth.returnedColumns' => 'id,username,password',
1010
'dbAuth.registerUser' => '1',
@@ -57,5 +57,8 @@
5757
return $response->withHeader('X-Time-Taken', 0.006/*microtime(true)*/ - $environment->start);
5858
}
5959
},
60+
'json.controllers' => 'records',
61+
'json.tables' => 'products',
62+
'json.fields' => 'properties',
6063
'debug' => false,
6164
];
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
===
2+
GET /records/products/1
3+
===
4+
200
5+
Content-Type: application/json; charset=utf-8
6+
Content-Length: 170
7+
8+
{"id":1,"name":"Calculator","price":"23.01","properties":{"depth":false,"model":"TRX-120","width":100,"height":null},"created_at":"1970-01-01 01:01:01","deleted_at":null}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
===
2+
PUT /records/products/1
3+
4+
{"properties":{"depth":true,"model":"TRX-120","width":100,"height":null}}
5+
===
6+
200
7+
Content-Type: application/json; charset=utf-8
8+
Content-Length: 1
9+
10+
1
11+
===
12+
GET /records/products/1
13+
===
14+
200
15+
Content-Type: application/json; charset=utf-8
16+
Content-Length: 169
17+
18+
{"id":1,"name":"Calculator","price":"23.01","properties":{"depth":true,"model":"TRX-120","width":100,"height":null},"created_at":"1970-01-01 01:01:01","deleted_at":null}
19+
===
20+
PUT /records/products/1
21+
22+
{"properties":{"depth":false,"model":"TRX-120","width":100,"height":null}}
23+
===
24+
200
25+
Content-Type: application/json; charset=utf-8
26+
Content-Length: 1
27+
28+
1
29+
===
30+
GET /records/products/1
31+
===
32+
200
33+
Content-Type: application/json; charset=utf-8
34+
Content-Length: 170
35+
36+
{"id":1,"name":"Calculator","price":"23.01","properties":{"depth":false,"model":"TRX-120","width":100,"height":null},"created_at":"1970-01-01 01:01:01","deleted_at":null}

0 commit comments

Comments
 (0)