RpcClient::getPayload()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.3731

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 5
cts 7
cp 0.7143
rs 9.6333
c 0
b 0
f 0
cc 4
nc 5
nop 1
crap 4.3731
1
<?php namespace Comodojo\RpcClient;
2
3
use \Comodojo\RpcClient\Interfaces\Transport as TransportInterface;
4
use \Comodojo\RpcClient\Interfaces\Processor as ProcessorInterface;
5
use \Comodojo\RpcClient\Traits\Protocol;
6
use \Comodojo\RpcClient\Traits\Encryption;
7
use \Comodojo\RpcClient\Traits\Encoding;
8
use \Comodojo\RpcClient\Processor\JsonProcessor;
9
use \Comodojo\RpcClient\Processor\XmlProcessor;
10
use \Comodojo\RpcClient\Components\HttpTransport;
11
use \Comodojo\RpcClient\Components\RequestManager;
12
use \Comodojo\Foundation\Logging\Manager as LogManager;
13
use \Comodojo\Foundation\Logging\LoggerTrait;
14
use \Psr\Log\LoggerInterface;
15
use \Comodojo\Exception\RpcException;
16
use \Comodojo\Exception\HttpException;
17
use \Comodojo\Exception\XmlrpcException;
18
use \InvalidArgumentException;
19
use \Exception;
20
21
/**
22
 * Comodojo RPC client. It's able to talk in XML and JSON (2.0).
23
 *
24
 * It optionally supports a not standard encrypted transport
25
 *
26
 * @package     Comodojo Spare Parts
27
 * @author      Marco Giovinazzi <[email protected]>
28
 * @license     MIT
29
 *
30
 * LICENSE:
31
 *
32
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38
 * THE SOFTWARE.
39
 */
40
41
class RpcClient {
42
43
    use Protocol;
44
    use Encryption;
45
    use Encoding;
46
    use LoggerTrait;
47
48
    const JSONRPC = "JSON";
49
50
    const XMLRPC = "XML";
51
52
    /**
53
     * Autoclean requests
54
     *
55
     * @var string
56
     */
57
    private $autoclean = true;
58
59
    /**
60
     * @var TransportInterface
61
     */
62
    private $transport;
63
64
    /**
65
     * @var RequestManager
66
     */
67
    private $request;
68
69
    /**
70
     * @var JsonProcessor
71
     */
72
    private $json_processor;
73
74
    /**
75
     * @var XmlProcessor
76
     */
77
    private $xml_processor;
78
79
    /**
80
     * Class constructor
81
     *
82
     * @param string $server
83
     *  Remote RPC server address
84
     * @param LoggerInterface $logger
85
     *  Logger interface
86
     * @param TransportInterface $transport
87
     *  Transport Interface
88
     * @throws InvalidArgumentException
89
     * @throws Exception
90
     */
91 63
    public function __construct(
92
        $server,
93
        LoggerInterface $logger = null,
94
        TransportInterface $transport = null
95
    ) {
96
97 63
        if ( empty($server) ) throw new InvalidArgumentException("Invalid RPC server address");
98
99 63
        $this->setLogger(
100 63
            is_null($logger) ?
101 63
                LogManager::create('rpcclient', false)->getLogger() :
102 42
                $logger
103 21
            );
104
105 63
        $this->request = new RequestManager();
106
107 63
        $this->json_processor = new JsonProcessor($this->getEncoding(), $this->getLogger());
108
109 63
        $this->xml_processor = new XmlProcessor($this->getEncoding(), $this->getLogger());
110
111
        try {
112
113 63
            $this->transport = empty($transport) ? new HttpTransport($server) : $transport;
114
115 21
        } catch (Exception $e) {
116
117
            throw $e;
118
119
        }
120
121 63
    }
122
123 63
    public function getTransport() {
124
125 63
        return $this->transport;
126
127
    }
128
129 63
    public function getRequest() {
130
131 63
        return $this->request;
132
133
    }
134
135
    /**
136
     * Set autoclean on/off
137
     *
138
     * @param bool $mode
139
     *  If true, requests will be removed from queue at each send()
140
     *
141
     * @return self
142
     */
143
    public function setAutoclean($mode = true) {
144
145
        $this->autoclean = filter_var($mode, FILTER_VALIDATE_BOOLEAN);
146
147
        return $this;
148
149
    }
150
151 63
    public function getAutoclean() {
152
153 63
        return $this->autoclean;
154
155
    }
156
157 63
    public function addRequest(RpcRequest $request) {
158
159 63
        $this->request->add($request);
160
161 63
        return $this;
162
163
    }
164
165 63
    public function getPayload(ProcessorInterface $processor = null) {
166
167 63
        $requests = $this->getRequest()->get();
168
169 63
        if ( empty($requests) ) throw new Exception("No request to send");
170
171 63
        $processor = is_null($processor) ? $this->getProcessor() : $processor;
172
173
        try {
174
175 63
            return $processor->encode($requests);
176
177
        } catch (Exception $e) {
178
179
            throw $e;
180
181
        }
182
183
    }
184
185
    /**
186
     * Send request(s) to server
187
     *
188
     * @return mixed
189
     *
190
     * @throws RpcException
191
     * @throws HttpException
192
     * @throws XmlrpcException
193
     * @throws Exception
194
     */
195 63
    public function send() {
196
197 63
        $protocol = $this->getProtocol();
198
199 63
        $content_type = $protocol == self::XMLRPC ? "text/xml" : "application/json";
200
201 63
        $processor = $this->getProcessor();
202
203
        try {
204
205 63
            $payload = $this->getPayload($processor);
206
207 63
            $response = $this->getTransport()
208 63
                ->performCall(
209 63
                    $this->logger,
210 63
                    $payload,
211 63
                    $content_type,
212 63
                    $this->getEncryption()
213 21
                );
214
215 63
            $result = $processor->decode($response);
216
217 21
        } catch (HttpException $he) {
218
219
            throw $he;
220
221
        } catch (RpcException $re) {
222
223
            throw $re;
224
225
        } catch (XmlrpcException $xe) {
226
227
            throw $xe;
228
229
        } catch (Exception $e) {
230
231
            throw $e;
232
233
        }
234
235 63
        if ( $this->getAutoclean() ) $this->getRequest()->clean();
236
237 63
        return $result;
238
239
    }
240
241 63
    private function getProcessor() {
242
243 63
        if ( $this->getProtocol() == self::XMLRPC ) {
244
245 39
            $processor = $this->xml_processor;
246
247 13
        } else {
248
249 24
            $processor = $this->json_processor;
250
251
        }
252
253 63
        return $processor->setEncoding($this->getEncoding());
254
255
    }
256
257
}
258