SoapCaller::call()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.5435

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 3
eloc 16
nc 3
nop 2
dl 0
loc 21
ccs 8
cts 18
cp 0.4444
crap 4.5435
rs 9.7333
c 4
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\Finkok;
6
7
use JsonSerializable;
8
use Psr\Log\LoggerAwareInterface;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\NullLogger;
11
use RuntimeException;
12
use SoapClient;
13
use stdClass;
14
use Throwable;
15
16
class SoapCaller implements LoggerAwareInterface
17
{
18
    /** @var SoapClient */
19
    private $soapClient;
20
21
    /** @var array<mixed> */
22
    private $extraParameters;
23
24
    /** @var LoggerInterface */
25
    private $logger;
26
27
    /**
28
     * @param SoapClient $soapClient
29
     * @param array<mixed> $extraParameters
30
     */
31 96
    public function __construct(SoapClient $soapClient, array $extraParameters = [])
32
    {
33 96
        $this->soapClient = $soapClient;
34 96
        $this->extraParameters = $extraParameters;
35 96
        $this->logger = new NullLogger();
36
    }
37
38 65
    private function soapClient(): SoapClient
39
    {
40 65
        return $this->soapClient;
41
    }
42
43
    /** @return array<mixed> */
44 68
    public function extraParameters(): array
45
    {
46 68
        return $this->extraParameters;
47
    }
48
49
    /**
50
     * @param string $methodName
51
     * @param array<mixed> $parameters
52
     * @return stdClass
53
     */
54 65
    public function call(string $methodName, array $parameters): stdClass
55
    {
56 65
        $finalParameters = $this->finalParameters($parameters);
57 65
        $soap = $this->soapClient();
58
        try {
59 65
            $result = $soap->__soapCall($methodName, [$finalParameters]);
60 65
            $this->logger->debug(strval(json_encode([
61 65
                $methodName => $this->extractSoapClientTrace($soap),
62 65
            ], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)));
63
            /** @var stdClass $result */
64 65
            return $result;
65
        } catch (Throwable $exception) {
66
            $this->logger->error(strval(json_encode(
67
                array_merge(
68
                    ['method' => $methodName, 'parameters' => $finalParameters],
69
                    $this->extractSoapClientTrace($soap),
70
                    ['exception' => ($exception instanceof JsonSerializable) ? $exception : print_r($exception, true)]
71
                ),
72
                JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
73
            )));
74
            throw new RuntimeException(sprintf('Fail soap call to %s', $methodName), 0, $exception);
75
        }
76
    }
77
78
    /**
79
     * @param SoapClient $soapClient
80
     * @return array<string, array<string, string>>
81
     * @noinspection PhpUsageOfSilenceOperatorInspection
82
     */
83 65
    protected function extractSoapClientTrace(SoapClient $soapClient): array
84
    {
85 65
        return [
86 65
            'request' => [
87 65
                'headers' => (string) @$soapClient->__getLastRequestHeaders(),
88 65
                'body' => (string) @$soapClient->__getLastRequest(),
89 65
            ],
90 65
            'response' => [
91 65
                'headers' => (string) @$soapClient->__getLastResponseHeaders(),
92 65
                'body' => (string) @$soapClient->__getLastResponse(),
93 65
            ],
94 65
        ];
95
    }
96
97
    /**
98
     * @param array<mixed> $parameters
99
     * @return array<mixed>
100
     */
101 65
    public function finalParameters(array $parameters): array
102
    {
103 65
        return array_merge($parameters, $this->extraParameters());
104
    }
105
106 65
    public function setLogger(LoggerInterface $logger): void
107
    {
108 65
        $this->logger = $logger;
109
    }
110
}
111