src/InsuranceCompany/Common/Subscriber/LogSubscriber.php line 107

Open in your IDE?
  1. <?php
  2. namespace App\InsuranceCompany\Common\Subscriber;
  3. use App\Entity\InsuranceCompany;
  4. use App\Repository\InsuranceCompanyRepository;
  5. use App\Service\CommunicationLoggerService;
  6. use App\SoapClient\Event\DecodeEvent;
  7. use App\SoapClient\Event\EncodeEvent;
  8. use App\SoapClient\Event\RequestEvent as CustomRequestEvent;
  9. use App\SoapClient\Event\ResponseEvent as CustomResponseEvent;
  10. use Doctrine\ORM\NonUniqueResultException;
  11. use Doctrine\ORM\NoResultException;
  12. use Phpro\SoapClient\Event\FaultEvent;
  13. use Phpro\SoapClient\Event\RequestEvent;
  14. use Phpro\SoapClient\Event\ResponseEvent;
  15. use Phpro\SoapClient\Type\RequestInterface;
  16. use Psr\Log\LoggerInterface;
  17. use RuntimeException;
  18. use Soap\Engine\HttpBinding\SoapRequest;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. /**
  21.  * Class CommonLogSubscriber
  22.  */
  23. class LogSubscriber implements EventSubscriberInterface
  24. {
  25.     /**
  26.      * Constructor
  27.      *
  28.      * @param LoggerInterface $logger
  29.      * @param CommunicationLoggerService $communicationLoggerService
  30.      * @param InsuranceCompanyRepository $insuranceCompanyRepository
  31.      */
  32.     public function __construct(
  33.         private readonly LoggerInterface            $logger,
  34.         private readonly CommunicationLoggerService $communicationLoggerService,
  35.         private readonly InsuranceCompanyRepository $insuranceCompanyRepository,
  36.     )
  37.     {
  38.     }
  39.     /**
  40.      * @param RequestEvent $event
  41.      */
  42.     public function onCallerRequest(RequestEvent $event)
  43.     {
  44.         $this->logger->debug(sprintf(
  45.             'SOAP Request: call {method}() with request %s',
  46.             print_r($event->getRequest(), true),
  47.         ), [
  48.             'method' => $event->getMethod(),
  49.             'request' => $event->getRequest(),
  50.         ]);
  51.     }
  52.     /**
  53.      * @param EncodeEvent $event
  54.      */
  55.     public function onEncode(EncodeEvent $event)
  56.     {
  57.         $this->logger->debug(sprintf(
  58.             '[{id}] SOAP Encode: call {method}() with arguments %s',
  59.             print_r($event->getArguments(), true),
  60.         ), [
  61.             'id' => $event->getRequestId(),
  62.             'method' => $event->getMethod(),
  63.             'arguments' => $event->getArguments(),
  64.         ]);
  65.     }
  66.     /**
  67.      * @param CustomRequestEvent $event
  68.      * @throws NonUniqueResultException
  69.      * @throws NoResultException
  70.      */
  71.     public function onEngineRequest(CustomRequestEvent $event)
  72.     {
  73.         $this->addRequestIdToRequestContent($event);
  74.         $this->logger->info('[{id}] SOAP Request: call {method}() with arguments of type {argumentTypes}', [
  75.             'id' => $event->getRequestId(),
  76.             'method' => $event->getMethod(),
  77.             'argumentTypes' => implode(', 'array_map(
  78.                 static fn($arg) => get_debug_type($arg),
  79.                 $event->getArguments(),
  80.             )),
  81.         ]);
  82.         $this->logger->debug(sprintf(
  83.             '[{id}] SOAP Encoded: call {method}() with arguments %s and request %s',
  84.             print_r($event->getArguments(), true),
  85.             print_r($event->getRequest(), true),
  86.         ), [
  87.             'id' => $event->getRequestId(),
  88.             'method' => $event->getMethod(),
  89.             'arguments' => $event->getArguments(),
  90.             'request' => $event->getRequest(),
  91.         ]);
  92.         $this->saveInCommunicationLog($event);
  93.     }
  94.     /**
  95.      * @param CustomResponseEvent $event
  96.      */
  97.     public function onEngineResponse(CustomResponseEvent $event)
  98.     {
  99.         $requestEvent $event->getRequestEvent();
  100.         $this->logger->debug(sprintf(
  101.             '[{id}] SOAP Response for call {method}() with response %s',
  102.             print_r($event->getResponse(), true),
  103.         ), [
  104.             'id' => $requestEvent->getRequestId(),
  105.             'method' => $requestEvent->getMethod(),
  106.             'response' => $event->getResponse(),
  107.         ]);
  108.     }
  109.     /**
  110.      * @param DecodeEvent $event
  111.      */
  112.     public function onDecode(DecodeEvent $event)
  113.     {
  114.         $requestEvent $event->getRequestEvent();
  115.         $this->logger->debug(sprintf(
  116.             '[{id}] SOAP decoded for call {method}() with response %s and result %s',
  117.             print_r($event->getResponse(), true),
  118.             print_r($event->getDecoded(), true),
  119.         ), [
  120.             'id' => $requestEvent->getRequestId(),
  121.             'method' => $requestEvent->getMethod(),
  122.             'request' => $requestEvent->getRequest(),
  123.             'response' => $event->getResponse(),
  124.             'decoded' => $event->getDecoded(),
  125.         ]);
  126.         $this->logger->info('[{id}] SOAP Response for call {method}() with result of type {resultType}', [
  127.             'id' => $requestEvent->getRequestId(),
  128.             'method' => $requestEvent->getMethod(),
  129.             'resultType' => get_debug_type($event->getDecoded()),
  130.         ]);
  131.     }
  132.     /**
  133.      * @param ResponseEvent $event
  134.      */
  135.     public function onCallerResponse(ResponseEvent $event)
  136.     {
  137.         $this->logger->debug(sprintf(
  138.             '[phpro/soap-client] response for call {method}(): %s',
  139.             print_r($event->getResponse(), true)
  140.         ), [
  141.             'method' => $event->getRequestEvent()->getMethod(),
  142.         ]);
  143.     }
  144.     /**
  145.      * @param FaultEvent $event
  146.      */
  147.     public function onFault(FaultEvent $event)
  148.     {
  149.         $requestEvent $event->getRequestEvent();
  150.         $exception $event->getSoapException();
  151.         $this->logger->error(sprintf(
  152.             '[phpro/soap-client] fault "%s" for request "%s" with params %s',
  153.             $exception->getMessage(),
  154.             $requestEvent->getMethod(),
  155.             print_r($requestEvent->getRequest(), true)
  156.         ), [
  157.             'exception' => $exception,
  158.         ]);
  159.         if (preg_match(
  160.             '/System\.InvalidOperationException: There is an error in XML document \((\d+), (\d+)\)\./',
  161.             $exception->getMessage(),
  162.             $matches
  163.         )) {
  164.             // TODO mark in log file where the error is
  165.             $xmlErrorRow = (int)$matches[1];
  166.             $xmlErrorColumn = (int)$matches[2];
  167.             $this->logger->error('XML error at row:col ' json_encode([$xmlErrorRow$xmlErrorColumn]), [
  168.                 'exception' => $exception,
  169.                 'xmlErrorRow' => $xmlErrorRow,
  170.                 'xmlErrorColumn' => $xmlErrorColumn,
  171.             ]);
  172.         }
  173.     }
  174.     /**
  175.      * {@inheritdoc}
  176.      * @noinspection PhpArrayShapeAttributeCanBeAddedInspection
  177.      */
  178.     public static function getSubscribedEvents(): array
  179.     {
  180.         return array(
  181.             RequestEvent::class => 'onCallerRequest',
  182.             EncodeEvent::class  => 'onEncode',
  183.             CustomRequestEvent::class  => 'onEngineRequest',
  184.             CustomResponseEvent::class => 'onEngineResponse',
  185.             DecodeEvent::class  => 'onDecode',
  186.             ResponseEvent::class => 'onCallerResponse',
  187.             FaultEvent::class    => 'onFault',
  188.         );
  189.     }
  190.     /**
  191.      * @param CustomRequestEvent $event
  192.      */
  193.     private function addRequestIdToRequestContent(CustomRequestEvent $event)
  194.     {
  195.         $request $event->getRequest();
  196.         $event->setRequest(new SoapRequest(
  197.             request$request->getRequest() . '<!-- BrokerSoft.RequestId: ' $event->getRequestId() . ' -->',
  198.             location$request->getLocation(),
  199.             action$request->getAction(),
  200.             version$request->getVersion(),
  201.             oneWay$request->getOneWay(),
  202.         ));
  203.     }
  204.     /**
  205.      * @param CustomRequestEvent $event
  206.      * @throws NoResultException
  207.      * @throws NonUniqueResultException
  208.      */
  209.     private function saveInCommunicationLog(CustomRequestEvent $event)
  210.     {
  211.         $arguments $event->getArguments();
  212.         $this->communicationLoggerService->createLog(
  213.             $this->detectInsuranceCompany($arguments),
  214.             $event->getRequestId(),
  215.             'SOAP',
  216.             $event->getMethod(),
  217.             $arguments,
  218.         );
  219.     }
  220.     /**
  221.      * @param array $request
  222.      * @return InsuranceCompany
  223.      * @throws NonUniqueResultException
  224.      * @throws NoResultException
  225.      */
  226.     private function detectInsuranceCompany(array $request): InsuranceCompany
  227.     {
  228.         $requestFirstElement reset($request);
  229.         if ($requestFirstElement instanceof RequestInterface) {
  230.             $type get_class($requestFirstElement);
  231.             $typeParts explode('\\'$type);
  232.             if (count($typeParts) < || $typeParts[0] !== 'App' || $typeParts[1] !== 'InsuranceCompany') {
  233.                 throw new RuntimeException('Unknown request type ' $type);
  234.             }
  235.             $shortNameLatin $typeParts[2];
  236.         }
  237.         else {
  238.             $shortNameLatin 'DZI';
  239.         }
  240.         return $this->insuranceCompanyRepository->findActiveByShortNameLatin($shortNameLatin);
  241.     }
  242. }