validateContentType($response); $body = $this->decodeBody($response->getBody()); $this->getJsonValidator()->validate($body); return $this->prepareResponse($body); } catch (InvalidJsonException $exception) { $errors = implode(', ', $exception->getValidationErrors()); return new WebhookResponse([], $exception->getMessage() . ': ' . $errors); } catch (\Exception $exception) { return new WebhookResponse([], $exception->getMessage()); } } /** * @return string */ public function getAcceptedContentType() { return 'application/json'; } /** * TODO: in case of eventId duplication respects last item * @param \stdClass $body * @return WebhookResponse */ private function prepareResponse($body) { $eventStatuses = []; foreach ($body->events as $eventRec) { $eventStatuses[$eventRec->eventId] = $eventRec->status; } return new WebhookResponse($eventStatuses, null); } /** * @param StreamInterface $body * @return \stdClass|mixed */ private function decodeBody(StreamInterface $body) { $stringBody = (string) $body; $decoded = json_decode($stringBody, false); if ($decoded === null) { throw new \InvalidArgumentException('Body is not a valid json: ' . json_last_error_msg()); } return $decoded; } private function validateContentType(ResponseInterface $response) { $headerValues = $response->getHeader('Content-Type'); if (count($headerValues) > 0) { $contentType = reset($headerValues); if (strcasecmp($contentType, $this->getAcceptedContentType()) !== 0) { throw new \InvalidArgumentException("Unsupported Content-Type: $contentType"); } } } /** * @return JsonValidator */ private function getJsonValidator() { /** @noinspection PhpIncompatibleReturnTypeInspection */ return $this->getServiceLocator()->get(JsonValidator::class); } }