From 7fa7fe63f814329069508a41bad9f450ddab100a Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Fri, 17 Feb 2023 21:42:32 +0200 Subject: [PATCH] api action return response --- application/Espo/Core/Api/Action.php | 4 +- .../Espo/Core/Api/RequestProcessor.php | 50 ++++++++++++++--- .../Espo/Core/Api/ResponseComposer.php | 53 +++++++++++++++++++ .../Crm/Tools/Calendar/Api/GetBusyRanges.php | 6 +-- .../Crm/Tools/Calendar/Api/GetCalendar.php | 14 ++--- .../Crm/Tools/Calendar/Api/GetTimeline.php | 6 +-- 6 files changed, 108 insertions(+), 25 deletions(-) create mode 100644 application/Espo/Core/Api/ResponseComposer.php diff --git a/application/Espo/Core/Api/Action.php b/application/Espo/Core/Api/Action.php index 9e726e8541..def512c801 100644 --- a/application/Espo/Core/Api/Action.php +++ b/application/Espo/Core/Api/Action.php @@ -43,11 +43,11 @@ interface Action * Process. * * @param Request $request A request. - * @param Response $response A response. Passed empty, to be written in the method. + * @return Response A response. Use ResponseComposer for building. * @throws BadRequest * @throws Forbidden * @throws NotFound * @throws Error */ - public function process(Request $request, Response $response): void; + public function process(Request $request): Response; } diff --git a/application/Espo/Core/Api/RequestProcessor.php b/application/Espo/Core/Api/RequestProcessor.php index 9e2617e583..ecff6c7af6 100644 --- a/application/Espo/Core/Api/RequestProcessor.php +++ b/application/Espo/Core/Api/RequestProcessor.php @@ -31,6 +31,9 @@ namespace Espo\Core\Api; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Authentication\AuthenticationFactory; +use Espo\Core\Exceptions\Error; +use Espo\Core\Exceptions\Forbidden; +use Espo\Core\Exceptions\NotFound; use Espo\Core\InjectableFactory; use Espo\Core\Utils\Config; use Espo\Core\Utils\Log; @@ -40,6 +43,7 @@ use Exception; use Psr\Http\Message\ResponseInterface as Psr7Response; use Psr\Http\Message\ServerRequestInterface as Psr7Request; use Slim\MiddlewareDispatcher; +use Slim\Psr7\Factory\ResponseFactory; use Throwable; use LogicException; @@ -94,6 +98,9 @@ class RequestProcessor /** * @throws BadRequest + * @throws Forbidden + * @throws Error + * @throws NotFound */ private function processInternal( ProcessData $processData, @@ -131,6 +138,9 @@ class RequestProcessor /** * @throws BadRequest + * @throws Forbidden + * @throws Error + * @throws NotFound */ private function processAfterAuth( ProcessData $processData, @@ -142,7 +152,7 @@ class RequestProcessor $actionClassName = $processData->getRoute()->getActionClassName(); if ($actionClassName) { - return $this->processAction($actionClassName, $requestWrapped, $responseWrapped); + return $this->processAction($actionClassName, $requestWrapped); } $controller = $this->getControllerName($processData); @@ -176,25 +186,49 @@ class RequestProcessor /** * @param class-string $actionClassName + * @throws Forbidden + * @throws BadRequest + * @throws NotFound + * @throws Error */ private function processAction( string $actionClassName, - RequestWrapper $requestWrapped, - ResponseWrapper $responseWrapped + RequestWrapper $requestWrapped ): Psr7Response { /** @var Action $action */ $action = $this->injectableFactory->create($actionClassName); - $action->process($requestWrapped, $responseWrapped); + $response = $action->process($requestWrapped); - $response = $responseWrapped->toPsr7(); + $psr7Response = $response instanceof ResponseWrapper ? + $response->toPsr7() : + self::responseToPsr7($response); - if (!$response->getHeader('Content-Type')) { - $response = $response->withHeader('Content-Type', self::DEFAULT_CONTENT_TYPE); + if (!$psr7Response->getHeader('Content-Type')) { + $psr7Response = $psr7Response->withHeader('Content-Type', self::DEFAULT_CONTENT_TYPE); } - return $response; + return $psr7Response; + } + + private static function responseToPsr7(Response $response): Psr7Response + { + $psr7Response = (new ResponseFactory())->createResponse(); + + $statusCode = $response->getStatusCode(); + $reason = $response->getReasonPhrase(); + $body = $response->getBody(); + + $psr7Response = $psr7Response + ->withStatus($statusCode, $reason) + ->withBody($body); + + foreach ($response->getHeaderNames() as $name) { + $psr7Response = $psr7Response->withHeader($name, $response->getHeaderAsArray($name)); + } + + return $psr7Response; } private function getControllerName(ProcessData $processData): string diff --git a/application/Espo/Core/Api/ResponseComposer.php b/application/Espo/Core/Api/ResponseComposer.php new file mode 100644 index 0000000000..d96ae485e6 --- /dev/null +++ b/application/Espo/Core/Api/ResponseComposer.php @@ -0,0 +1,53 @@ +|stdClass|scalar|null $data A data to encode. + */ + public static function json(mixed $data): Response + { + $psr7Response = (new ResponseFactory())->createResponse(); + + $response = new ResponseWrapper($psr7Response); + $response->writeBody(Json::encode($data)); + $response->setHeader('Content-Type', 'application/json'); + + return $response; + } +} diff --git a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetBusyRanges.php b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetBusyRanges.php index 254cd72bff..93243daffc 100644 --- a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetBusyRanges.php +++ b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetBusyRanges.php @@ -32,9 +32,9 @@ namespace Espo\Modules\Crm\Tools\Calendar\Api; use Espo\Core\Api\Action; use Espo\Core\Api\Request; use Espo\Core\Api\Response; +use Espo\Core\Api\ResponseComposer; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Field\DateTime; -use Espo\Core\Utils\Json; use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem; use Espo\Modules\Crm\Tools\Calendar\Service; @@ -47,7 +47,7 @@ class GetBusyRanges implements Action { public function __construct(private Service $calendarService) {} - public function process(Request $request, Response $response): void + public function process(Request $request): Response { $from = $request->getQueryParam('from'); $to = $request->getQueryParam('to'); @@ -73,7 +73,7 @@ class GetBusyRanges implements Action $result->$userId = self::itemListToRaw($itemList); } - $response->writeBody(Json::encode($result)); + return ResponseComposer::json($result); } /** diff --git a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php index d62cf8342d..c2662e2761 100644 --- a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php +++ b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetCalendar.php @@ -32,11 +32,11 @@ namespace Espo\Modules\Crm\Tools\Calendar\Api; use Espo\Core\Api\Action; use Espo\Core\Api\Request; use Espo\Core\Api\Response; +use Espo\Core\Api\ResponseComposer; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Exceptions\Forbidden; use Espo\Core\Acl; use Espo\Core\Field\DateTime; -use Espo\Core\Utils\Json; use Espo\Entities\User; use Espo\Modules\Crm\Tools\Calendar\FetchParams; use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem; @@ -57,7 +57,7 @@ class GetCalendar implements Action private User $user ) {} - public function process(Request $request, Response $response): void + public function process(Request $request): Response { if (!$this->acl->check('Calendar')) { throw new Forbidden(); @@ -99,9 +99,7 @@ class GetCalendar implements Action $this->calendarService->fetchForTeams($teamIdList, $fetchParams) ); - $response->writeBody(Json::encode($raw)); - - return; + return ResponseComposer::json($raw); } if ($userIdList) { @@ -111,9 +109,7 @@ class GetCalendar implements Action $this->calendarService->fetchForUsers($userIdList, $fetchParams) ); - $response->writeBody(Json::encode($raw)); - - return; + return ResponseComposer::json($raw); } if (!$userId) { @@ -128,7 +124,7 @@ class GetCalendar implements Action $this->calendarService->fetch($userId, $fetchParams) ); - $response->writeBody(Json::encode($raw)); + return ResponseComposer::json($raw); } /** diff --git a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php index 390eeeb3d6..2541fbd1e2 100644 --- a/application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php +++ b/application/Espo/Modules/Crm/Tools/Calendar/Api/GetTimeline.php @@ -32,11 +32,11 @@ namespace Espo\Modules\Crm\Tools\Calendar\Api; use Espo\Core\Api\Action; use Espo\Core\Api\Request; use Espo\Core\Api\Response; +use Espo\Core\Api\ResponseComposer; use Espo\Core\Exceptions\BadRequest; use Espo\Core\Exceptions\Forbidden; use Espo\Core\Acl; use Espo\Core\Field\DateTime; -use Espo\Core\Utils\Json; use Espo\Modules\Crm\Tools\Calendar\FetchParams; use Espo\Modules\Crm\Tools\Calendar\Item as CalendarItem; use Espo\Modules\Crm\Tools\Calendar\Service; @@ -55,7 +55,7 @@ class GetTimeline implements Action private Acl $acl ) {} - public function process(Request $request, Response $response): void + public function process(Request $request): Response { if (!$this->acl->check('Calendar')) { throw new Forbidden(); @@ -102,7 +102,7 @@ class GetTimeline implements Action $result->$userId = self::itemListToRaw($itemList); } - $response->writeBody(Json::encode($result)); + return ResponseComposer::json($result); } /**