Completed
Push — master ( 214e7e...6e06f4 )
by Meng
02:10
created

RequestBuilder::prepareMessage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
namespace Meng\Soap\HttpBinding;
4
5
use Psr\Http\Message\RequestInterface;
6
use Psr\Http\Message\StreamInterface;
7
use Zend\Diactoros\Request;
8
use Zend\Diactoros\Stream;
9
10
/**
11
 * This class create PSR HTTP requests that embed SOAP messages.
12
 */
13
class RequestBuilder
14
{
15
    const SOAP11 = '1.1';
16
    const SOAP12 = '1.2';
17
18
    /**
19
     * @var string
20
     */
21
    private $endpoint;
22
    /**
23
     * @var string
24
     */
25
    private $soapVersion = self::SOAP11;
26
    /**
27
     * @var string
28
     */
29
    private $soapAction = '';
30
    /**
31
     * @var StreamInterface
32
     */
33
    private $soapMessage;
34
    /**
35
     * @var bool
36
     */
37
    private $hasSoapMessage = false;
38
    /**
39
     * @var string
40
     */
41
    private $httpMethod = 'POST';
42
43
    /**
44
     * @return RequestInterface
45
     */
46
    public function getSoapHttpRequest()
47
    {
48
        $this->validate();
49
        $headers = $this->prepareHeaders();
50
        $message = $this->prepareMessage();
51
        $request = new Request(
52
            $this->endpoint,
53
            $this->httpMethod,
54
            $message,
55
            $headers
56
        );
57
        $this->unsetAll();
58
        return $request;
59
    }
60
61
    /**
62
     * @param string $endpoint
63
     * @return self
64
     */
65
    public function setEndpoint($endpoint)
66
    {
67
        $this->endpoint = $endpoint;
68
        return $this;
69
    }
70
71
    /**
72
     * @return self
73
     */
74
    public function isSOAP11()
75
    {
76
        $this->soapVersion = self::SOAP11;
77
        return $this;
78
    }
79
80
    public function isSOAP12()
81
    {
82
        $this->soapVersion = self::SOAP12;
83
        return $this;
84
    }
85
86
87
    /**
88
     * @param string $soapAction
89
     * @return self
90
     */
91
    public function setSoapAction($soapAction)
92
    {
93
        $this->soapAction = $soapAction;
94
        return $this;
95
    }
96
97
    /**
98
     * @param StreamInterface $message
99
     * @return self
100
     */
101
    public function setSoapMessage($message)
102
    {
103
        $this->soapMessage = $message;
104
        $this->hasSoapMessage = true;
105
        return $this;
106
    }
107
108
    /**
109
     * @param string $method
110
     * @return self
111
     */
112
    public function setHttpMethod($method)
113
    {
114
        $this->httpMethod = $method;
115
        return $this;
116
    }
117
118
    private function validate()
119
    {
120
        $isValid = true;
121
122
        if (!$this->endpoint) {
123
            $isValid = false;
124
        }
125
126
        if (!$this->hasSoapMessage && $this->httpMethod == 'POST') {
127
            $isValid = false;
128
        }
129
130
        /**
131
         * SOAP 1.1 only defines HTTP binding with POST method.
132
         * @link https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383527
133
         */
134
        if ($this->soapVersion == self::SOAP11 && $this->httpMethod != 'POST') {
135
            $isValid = false;
136
        }
137
138
        /**
139
         * SOAP 1.2 only defines HTTP binding with POST and GET methods.
140
         * @link https://www.w3.org/TR/2007/REC-soap12-part0-20070427/#L10309
141
         */
142
        if ($this->soapVersion == self::SOAP12 && !in_array($this->httpMethod, ['GET', 'POST'])) {
143
            $isValid = false;
144
        }
145
146
        if (!$isValid) {
147
            throw new RequestException;
148
        }
149
    }
150
151
    /**
152
     * @return array
153
     */
154
    private function prepareHeaders()
155
    {
156
        if ($this->soapVersion == self::SOAP11) {
157
            return $this->prepareSoap11Headers();
158
        } else {
159
            return $this->prepareSoap12Headers();
160
        }
161
    }
162
163
    /**
164
     * @link https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526
165
     * @return array
166
     */
167
    private function prepareSoap11Headers()
168
    {
169
        $headers = [];
170
        $headers['Content-Length'] = strlen($this->soapMessage->getContents());
171
        $headers['SOAPAction'] = $this->soapAction;
172
        $headers['Content-Type'] = 'text/xml; charset="utf-8"';
173
        return $headers;
174
    }
175
176
    /**
177
     * SOSPAction header is removed in SOAP 1.2 and now expressed as a value of
178
     * an (optional) "action" parameter of the "application/soap+xml" media type.
179
     * @link https://www.w3.org/TR/soap12-part0/#L4697
180
     * @return array
181
     */
182
    private function prepareSoap12Headers()
183
    {
184
        $headers = [];
185
        if ($this->httpMethod == 'POST') {
186
            $headers['Content-Length'] = strlen($this->soapMessage->getContents());
187
            $headers['Content-Type'] = 'application/soap+xml; charset="utf-8"' . '; action="' . $this->soapAction . '"';
188
        } else {
189
            $headers['Accept'] = 'application/soap+xml';
190
        }
191
        return $headers;
192
    }
193
194
    /**
195
     * @return StreamInterface
196
     */
197
    private function prepareMessage()
198
    {
199
        if ($this->httpMethod == 'POST') {
200
            return $this->soapMessage;
201
        } else {
202
            return new Stream(fopen('php://temp', 'r'));
203
        }
204
    }
205
206
    private function unsetAll()
207
    {
208
        unset($this->endpoint);
209
        $this->soapAction = '';
210
        $this->soapVersion = SOAP_1_1;
0 ignored issues
show
Documentation Bug introduced by
The property $soapVersion was declared of type string, but SOAP_1_1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
211
        $this->hasSoapMessage = false;
212
        $this->httpMethod = 'POST';
213
    }
214
}