Completed
Pull Request — master (#7)
by Ian
05:36
created

Client   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 12

Test Coverage

Coverage 79.41%

Importance

Changes 0
Metric Value
wmc 14
lcom 0
cbo 12
dl 0
loc 132
ccs 54
cts 68
cp 0.7941
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
C __call() 0 67 8
A buildHeaders() 0 7 1
A findOperation() 0 13 4
1
<?php
2
namespace GoetasWebservices\SoapServices\SoapClient;
3
4
use GoetasWebservices\SoapServices\SoapClient\Arguments\ArgumentsReader;
5
use GoetasWebservices\SoapServices\SoapClient\Arguments\ArgumentsReaderInterface;
6
use GoetasWebservices\SoapServices\SoapClient\Arguments\Headers\Handler\HeaderHandler;
7
use GoetasWebservices\SoapServices\SoapClient\Exception\ClientException;
8
use GoetasWebservices\SoapServices\SoapClient\Exception\FaultException;
9
use GoetasWebservices\SoapServices\SoapClient\Exception\ServerException;
10
use GoetasWebservices\SoapServices\SoapClient\Exception\SoapException;
11
use GoetasWebservices\SoapServices\SoapClient\Result\ResultCreator;
12
use GoetasWebservices\SoapServices\SoapClient\Result\ResultCreatorInterface;
13
use GoetasWebservices\SoapServices\SoapCommon as SoapCommon;
14
use GoetasWebservices\SoapServices\SoapCommon\SoapEnvelope\Parts\Fault;
15
use GoetasWebservices\SoapServices\SoapEnvelope;
16
use Http\Client\Exception\HttpException;
17
use Http\Client\HttpClient;
18
use Http\Message\MessageFactory;
19
use JMS\Serializer\Serializer;
20
21
class Client
22
{
23
    /**
24
     * @var Serializer
25
     */
26
    protected $serializer;
27
    /**
28
     * @var array
29
     */
30
    protected $serviceDefinition;
31
    /**
32
     * @var HttpClient
33
     */
34
    protected $client;
35
36
    /**
37
     * @var MessageFactory
38
     */
39
    protected $messageFactory;
40
41
    /**
42
     * @var ResultCreatorInterface
43
     */
44
    private $resultCreator;
45
46
    /**
47
     * @var ArgumentsReaderInterface
48
     */
49
    private $argumentsReader;
50
51
52 17
    public function __construct(array $serviceDefinition, Serializer $serializer, MessageFactory $messageFactory, HttpClient $client, HeaderHandler $headerHandler)
53
    {
54 17
        $this->serviceDefinition = $serviceDefinition;
55 17
        $this->serializer = $serializer;
56
57 17
        $this->client = $client;
58 17
        $this->messageFactory = $messageFactory;
59 17
        $this->argumentsReader = new ArgumentsReader($this->serializer, $headerHandler);
60 17
        $this->resultCreator = new ResultCreator($this->serializer, !empty($serviceDefinition['unwrap']));
61 17
    }
62
63 15
    public function __call($functionName, array $args)
64
    {
65 15
        $soapOperation = $this->findOperation($functionName, $this->serviceDefinition);
66 15
        $message = $this->argumentsReader->readArguments($args, $soapOperation['input']);
67
68 15
        $xmlMessage = $this->serializer->serialize($message, 'xml');
0 ignored issues
show
Bug introduced by
It seems like $message defined by $this->argumentsReader->...soapOperation['input']) on line 66 can also be of type null; however, JMS\Serializer\Serializer::serialize() does only seem to accept object|array|integer|double|string|boolean, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
69 15
        $headers = $this->buildHeaders($soapOperation);
70 15
        $request = $this->messageFactory->createRequest('POST', $this->serviceDefinition['endpoint'], $headers, $xmlMessage);
71
72
        try {
73 15
            $response = $this->client->sendRequest($request);
74 10
            $xmlResponse = strpos($response->getHeaderLine('Content-Type'), 'text/xml') === 0;
75 10
            $soapXmlResponse = strpos($response->getHeaderLine('Content-Type'), 'application/soap+xml') === 0;
76 10
            if (!$xmlResponse && !$soapXmlResponse) {
77 1
                throw new ServerException(
78 1
                    $response,
79 1
                    $request,
80 1
                    "Unexpected content type '" . $response->getHeaderLine('Content-Type') . "'"
81 1
                );
82
            }
83
84
            // fast return if no return is expected
85 9
            if (!count($soapOperation['output']['parts'])) {
86 2
                return null;
87
            }
88
89 7
            $body = (string)$response->getBody();
90 7
            if (strpos($body, ':Fault>')!==false) {
91
                $fault = $this->serializer->deserialize($body, Fault::class, 'xml');
92
                throw new FaultException(
93
                    $fault,
94
                    $response,
95
                    $request,
96
                    "SOAP Fault",
97
                    null,
98
                    new \Exception()
99
                );
100
            }
101
102 7
            $response = $this->serializer->deserialize($body, $soapOperation['output']['message_fqcn'], 'xml');
103 13
        } catch (HttpException $e) {
104
105 5
            $xmlResponse = strpos($e->getResponse()->getHeaderLine('Content-Type'), 'text/xml') === 0;
106 5
            $soapXmlResponse = strpos($e->getResponse()->getHeaderLine('Content-Type'), 'application/soap+xml') === 0;
107 5
            if ($xmlResponse || $soapXmlResponse) {
108 3
                $fault = $this->serializer->deserialize((string)$e->getResponse()->getBody(), Fault::class, 'xml');
109 3
                throw new FaultException(
110 3
                    $fault,
111 3
                    $e->getResponse(),
112 3
                    $e->getRequest(),
113 3
                    $e->getMessage(),
114 3
                    null,
115
                    $e
116 3
                );
117
            } else {
118 2
                throw new ServerException(
119 2
                    $e->getResponse(),
120 2
                    $e->getRequest(),
121 2
                    $e->getMessage(),
122 2
                    null,
123
                    $e
124 2
                );
125
            }
126
        }
127
128 7
        return $this->resultCreator->prepareResult($response, $soapOperation['output']);
129
    }
130
131 15
    protected function buildHeaders(array $operation)
132
    {
133
        return [
134 15
            'Content-Type' => 'text/xml; charset=utf-8',
135 15
            'SoapAction' => '"' . $operation['action'] . '"',
136 15
        ];
137
    }
138
139 15
    protected function findOperation($functionName, array $serviceDefinition)
140
    {
141 15
        if (isset($serviceDefinition['operations'][$functionName])) {
142 15
            return $serviceDefinition['operations'][$functionName];
143
        }
144
145
        foreach ($serviceDefinition['operations'] as $opName => $operation) {
146
            if (strtolower($functionName) == strtolower($opName)) {
147
                return $operation;
148
            }
149
        }
150
        throw new ClientException("Can not find an operation to run $functionName service call");
151
    }
152
}
153