<?php
/*
* Copyright (c) Pickware GmbH. All rights reserved.
* This file is part of software that is released under a proprietary license.
* You must not copy, modify, distribute, make publicly available, or execute
* its contents or parts thereof without express permission by the copyright
* holder, unless otherwise permitted by law.
*/
declare(strict_types=1);
namespace Pickware\ApiErrorHandlingBundle\ControllerExceptionHandling;
use Exception;
use Pickware\HttpUtils\JsonApi\JsonApiError;
use Psr\Log\LoggerInterface;
use Shopware\Core\Framework\Api\Context\AdminApiSource;
use Shopware\Core\Framework\Context;
use Shopware\Core\PlatformRequest;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
class AdminApiJsonApiErrorExceptionLocalization implements EventSubscriberInterface
{
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public static function getSubscribedEvents(): array
{
return [
ResponseEvent::class => [
'onResponseEvent',
0,
],
];
}
public function onResponseEvent(ResponseEvent $event): void
{
$response = $event->getResponse();
if ($response->getStatusCode() < 400) {
return;
}
/** @var Context $context */
$context = $event->getRequest()->attributes->get(PlatformRequest::ATTRIBUTE_CONTEXT_OBJECT);
// Only the Admin API uses JSON API.
if (!$context || !($context->getSource() instanceof AdminApiSource)) {
return;
}
// We catch the error because we don't want to obfuscate the original error
try {
$content = json_decode($response->getContent(), true, 512, JSON_THROW_ON_ERROR);
} catch (Exception $error) {
$this->logger->error(
sprintf(
'Caught an json decode exception while trying to localize error in %s',
self::class,
),
[
'responseContent' => $response->getContent(),
'caughtException' => $error,
],
);
return;
}
$errors = $content['errors'] ?? null;
if (!$errors) {
return;
}
$locales = $event->getRequest()->getLanguages();
$localizedErrors = [];
foreach ($errors as $error) {
if (!$error || !($error['meta'] ?? null) || !($error['meta']['_localizedProperties'] ?? null)) {
$localizedErrors[] = $error;
continue;
}
$localizedErrors[] = (new JsonApiError($error))->getLocalizedCopy($locales);
}
$content['errors'] = $localizedErrors;
$response->setContent(json_encode($content));
$event->setResponse($response);
}
}