Passed
Push — master ( 15770c...ea0752 )
by Petr
08:09
created

Helper::getConnectionParams()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 7
nop 1
dl 0
loc 16
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace kalanis\RemoteRequest;
4
5
6
use kalanis\RemoteRequest\Connection;
7
use kalanis\RemoteRequest\Interfaces;
8
use kalanis\RemoteRequest\Sockets;
9
10
11
/**
12
 * Class Helper
13
 * @package kalanis\RemoteRequest
14
 * Simplified reading from remote machine with a whole power of RemoteRequest and mainly streams underneath
15
 * -> throw Curl into /dev/null
16
 */
17
class Helper
18
{
19
    /** @var Interfaces\IRRTranslations */
20
    protected static $lang = null; // translations
21
    /** @var string */
22
    protected $link = ''; // target
23
    /** @var string|string[]|array<string|int, string|int> */
24
    protected $postContent = ''; // what to say to the target
25
    /** @var array<string, string|int|bool|null> */
26
    protected $connectionParams = [
27
        'timeout' => 30,
28
        'maxLength' => 0,
29
        'method' => 'get',
30
        'multipart' => false,
31
        'permanent' => false,
32
        'sequence' => 0,
33
        'secret' => 0,
34
        'seek' => 0,
35
    ];
36
    /** @var array<string, array<string, string>|string> */
37
    protected $contextParams = [];
38
39
    /**
40
     * @param string $link link to remote source (server, page, ...)
41
     * @param string|string[] $postContent array(key=>value) for http or fsp, string otherwise
42
     * @param array<string, string|int|bool|null> $connectionParams overwrite default values for connection
43
     * @param array<string, array<string, string>|string> $contextParams added to stream context (like skipping ssl checkup)
44
     * @throws RequestException
45
     * @return string
46
     */
47
    public static function getRemoteContent(string $link, $postContent = '', array $connectionParams = [], array $contextParams = []): string
48
    {
49
        $lib = new Helper();
50
        $lib
51
            ->setLink($link)
52
            ->setPostContent($postContent)
53
            ->setConnectionParams($connectionParams)
54
            ->setContextParams($contextParams)
55
        ;
56
        return $lib->getResponse()->getContent();
57
    }
58
59
    public static function fillLang(?Interfaces\IRRTranslations $lang = null): void
60
    {
61
        if ($lang) {
62
            static::$lang = $lang;
63
        }
64
        if (empty(static::$lang)) {
65
            static::$lang = new Translations();
66
        }
67
    }
68
69
    public function setLink(string $link): self
70
    {
71
        $this->link = $link;
72
        return $this;
73
    }
74
75
    /**
76
     * @param string|string[]|array<string|int, string|int> $postContent
77
     * @return $this
78
     */
79
    public function setPostContent($postContent = ''): self
80
    {
81
        $this->postContent = $postContent;
82
        return $this;
83
    }
84
85
    /**
86
     * @param array<string, string|int|bool|null> $params
87
     * @return $this
88
     */
89
    public function setConnectionParams(array $params = []): self
90
    {
91
        $this->connectionParams = array_merge($this->connectionParams, $params);
92
        return $this;
93
    }
94
95
    /**
96
     * @param array<string, array<string, string>|string> $params
97
     * @return $this
98
     */
99
    public function setContextParams(array $params = []): self
100
    {
101
        $this->contextParams = $params;
102
        return $this;
103
    }
104
105
    /**
106
     * @throws RequestException
107
     * @return Protocols\Dummy\Answer
108
     */
109
    public function getResponse(): Protocols\Dummy\Answer
110
    {
111
        static::fillLang();
112
        $parsedLink = parse_url($this->link);
113
        if (false === $parsedLink) {
114
            throw new RequestException(static::$lang->rrHelpInvalidLink($this->link));
115
        }
116
        $schema = !empty($parsedLink["scheme"]) ? strtolower($parsedLink["scheme"]) : '' ;
117
        $libParams = $this->getFilledConnectionParams($schema, $parsedLink);
118
        $libQuery = $this->getLibRequest($schema, $parsedLink, $libParams);
119
        return $this->getLibResponseProcessor($schema)->setResponse(
120
            $this->getLibConnection($libQuery)
121
                ->setConnectionParams($libParams)
122
                ->setData($libQuery)
123
                ->process()
124
                ->getResponse()
125
        );
126
    }
127
128
    protected function getLibConnection(Protocols\Dummy\Query $libQuery): Connection\Processor
129
    {
130
        return new Connection\Processor(static::$lang, $this->getLibSockets($libQuery));
131
    }
132
133
    protected function getLibSockets(Protocols\Dummy\Query $libQuery): ?Sockets\ASocket
134
    {
135
        if (!empty($this->contextParams)) {
136
            $processing = new Sockets\Stream(static::$lang);
137
            return $processing->setContextOptions($this->contextParams);
138
        } elseif ($this->connectionParams['permanent']) {
139
            return new Sockets\PfSocket(static::$lang);
140
        } elseif ($libQuery instanceof Protocols\Fsp\Query) {
141
            return new Sockets\Socket(static::$lang);
142
        } else {
143
            return new Sockets\FSocket(static::$lang);
144
        }
145
    }
146
147
    /**
148
     * @param string $schema
149
     * @param array<string, int|string> $parsedLink from parse_url()
150
     * @throws RequestException
151
     * @return Connection\Params\AParams
152
     */
153
    protected function getFilledConnectionParams(string $schema, $parsedLink): Connection\Params\AParams
154
    {
155
        $libParams = $this->getConnectionParams($schema);
156
        return $libParams->setTarget(
157
            strval($parsedLink["host"]),
158
            empty($parsedLink["port"]) ? $libParams->getPort() : intval($parsedLink["port"]),
159
            empty($this->connectionParams['timeout']) ? null : intval($this->connectionParams['timeout'])
160
        );
161
    }
162
163
    /**
164
     * @param string $schema
165
     * @throws RequestException
166
     * @return Connection\Params\AParams
167
     */
168
    protected function getConnectionParams(string $schema): Connection\Params\AParams
169
    {
170
        switch ($schema) {
171
            case 'tcp':
172
                return new Connection\Params\Tcp();
173
            case 'udp':
174
            case 'fsp':
175
                return new Connection\Params\Udp();
176
            case 'http':
177
                return new Connection\Params\Tcp();
178
            case 'https':
179
                return new Connection\Params\Ssl();
180
            case 'file':
181
                return new Connection\Params\File();
182
            default:
183
                throw new RequestException(static::$lang->rrHelpInvalidProtocolSchema($schema));
184
        }
185
    }
186
187
    /**
188
     * @param string $schema
189
     * @param array<string, int|string> $parsed from parse_url()
190
     * @param Interfaces\ITarget $settings
191
     * @throws RequestException
192
     * @return Protocols\Dummy\Query
193
     */
194
    protected function getLibRequest(string $schema, array $parsed, Interfaces\ITarget $settings): Protocols\Dummy\Query
195
    {
196
        switch ($schema) {
197
            case 'tcp':
198
            case 'udp':
199
            case 'file':
200
                $query = new Protocols\Dummy\Query();
201
                $query->maxLength = is_null($this->connectionParams['maxLength']) ? null : intval($this->connectionParams['maxLength']);
202
                $query->body = strval($this->postContent);
203
                return $query;
204
            case 'fsp':
205
                $query = new Protocols\Fsp\Query();
206
                return $query
207
                    ->setCommand(intval($this->connectionParams['method']))
208
                    ->setSequence(intval($this->connectionParams['sequence']))
209
                    ->setKey(intval($this->connectionParams['secret']))
210
                    ->setFilePosition(intval($this->connectionParams['seek']))
211
                    ->setContent(strval($this->postContent))
212
                ;
213
            case 'http':
214
            case 'https':
215
                if (isset($parsed['user'])) {
216
                    $query = new Protocols\Http\Query\AuthBasic();
217
                    $query->setCredentials(
218
                        strval($parsed['user']),
219
                        isset($parsed['pass']) ? strval($parsed['pass']) : ''
220
                    );
221
                } else {
222
                    $query = new Protocols\Http\Query();
223
                }
224
                $query->maxLength = is_null($this->connectionParams['maxLength']) ? null : intval($this->connectionParams['maxLength']);
225
                return $query
226
                    ->setRequestSettings($settings)
227
                    ->setPath($parsed['path'] . (!empty($parsed['query']) ? '?' . $parsed['query'] : '' ))
228
                    ->setMethod($this->getMethod())
229
                    ->setInline(boolval($this->connectionParams['multipart']))
230
                    ->addValues(empty($this->postContent) ? [] : (array) $this->postContent)
231
                ;
232
            default:
233
                throw new RequestException(static::$lang->rrHelpInvalidRequestSchema($schema));
234
        }
235
    }
236
237
    protected function getMethod(): string
238
    {
239
        $method = strtoupper(strval($this->connectionParams['method']));
240
        return (in_array($method, ['GET', 'POST', 'PUT', 'DELETE'])) ? $method : 'GET' ;
241
    }
242
243
    /**
244
     * @param string $schema
245
     * @throws RequestException
246
     * @return Protocols\Dummy\Answer
247
     */
248
    protected function getLibResponseProcessor(string $schema): Protocols\Dummy\Answer
249
    {
250
        switch ($schema) {
251
            case 'tcp':
252
            case 'udp':
253
            case 'file':
254
                return new Protocols\Dummy\Answer();
255
            case 'fsp':
256
                return new Protocols\Fsp\Answer(static::$lang);
257
            case 'http':
258
            case 'https':
259
                return new Protocols\Http\Answer(static::$lang);
260
            default:
261
                throw new RequestException(static::$lang->rrHelpInvalidResponseSchema($schema));
262
        }
263
    }
264
}
265