FtpBuilder::build()   A
last analyzed

Complexity

Conditions 5
Paths 12

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 12
nop 1
dl 0
loc 28
rs 9.4888
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Keppler\Url\Builder\Schemes\Ftp;
5
6
use Keppler\Url\Builder\Schemes\Ftp\Bags\FtpMutablePath;
7
use Keppler\Url\Interfaces\Mutable\MutableSchemeInterface;
8
use Keppler\Url\Scheme\Schemes\Ftp\Bags\FtpImmutablePath;
9
use Keppler\Url\Scheme\Schemes\Ftp\FtpImmutable;
10
11
/**
12
 * Note that the following class makes no assumption regarding url encoding
13
 * the ftp url is taken AS IS and will not be decoded or encoded
14
 * url encoded strings WILL result in errors
15
 *
16
 * ftpurl = "ftp://" login [ "/" fpath [ ";type=" ftptype ]]
17
 *
18
 * ftp://[user[:password]@]host[:port]/url-path
19
 *
20
 * @see     https://tools.ietf.org/html/rfc1738
21
 *
22
 * Class FtpImmutable
23
 *
24
 * @package Keppler\Url\Schemes\Ftp
25
 */
26
class FtpBuilder implements MutableSchemeInterface
27
{
28
    /**
29
     * The default scheme for this class
30
     *
31
     * @var string
32
     */
33
    const SCHEME = 'ftp';
34
35
    /**
36
     * userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
37
     *
38
     * @var string
39
     */
40
    private $user = '';
41
42
    /**
43
     * Usage is highly discouraged
44
     *
45
     * @var string
46
     */
47
    private $password = '';
48
49
    /**
50
     * host = IP-literal / IPv4address / reg-name
51
     *
52
     * @var string
53
     */
54
    private $host = '';
55
56
    /**
57
     * port = *DIGIT
58
     *
59
     * Ports can't be negative, -1 should be considered the default value and
60
     * ignored
61
     *
62
     * INVALID-PORT
63
     *  Either the local or foreign port was improperly
64
     *  specified.  This should be returned if either or
65
     *  both of the port ids were out of range (TCP port
66
     *  numbers are from 1-65535), negative integers, reals or
67
     *  in any fashion not recognized as a non-negative integer.
68
     *
69
     * @see https://www.ietf.org/rfc/rfc1413.txt
70
     * @var int
71
     */
72
    private $port = -1;
73
74
    /**
75
     * @var FtpMutablePath
76
     */
77
    private $pathBag;
78
79
    /**
80
     * FtpBuilder constructor.
81
     *
82
     * @param FtpImmutable|null $ftp
83
     */
84
    public function __construct(FtpImmutable $ftp = null)
85
    {
86
        $this->pathBag = new FtpMutablePath();
87
88
        if (null !== $ftp) {
89
            $this->populate($ftp);
90
91
            $this->user = $ftp->getUser();
92
            $this->password = $ftp->getPassword();
93
            $this->host = $ftp->getHost();
94
            $this->port = null === $ftp->getPort() ? -1 : $ftp->getPort();
95
        }
96
    }
97
98
    ///////////////////////////
99
    /// PRIVATE FUNCTIONS  ///
100
    /////////////////////////
101
    /**
102
     * @param FtpImmutable $ftp
103
     */
104
    private function populate(FtpImmutable $ftp): void
105
    {
106
        foreach ($ftp->getPathBag()->all() as $key => $value) {
107
            $this->pathBag->set($key, $value);
108
        }
109
    }
110
111
    //////////////////////////
112
    /// GETTER FUNCTIONS  ///
113
    ////////////////////////
114
115
    /**
116
     * @return FtpMutablePath
117
     */
118
    public function getPathBag(): FtpMutablePath
119
    {
120
        return $this->pathBag;
121
    }
122
123
    /**
124
     * @return string
125
     */
126
    public function getUser(): string
127
    {
128
        return $this->user;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    public function getPassword(): string
135
    {
136
        return $this->password;
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    public function getHost(): string
143
    {
144
        return $this->host;
145
    }
146
147
    /**
148
     * @return int
149
     */
150
    public function getPort(): int
151
    {
152
        return $this->port;
153
    }
154
155
    //////////////////////////
156
    /// SETTER FUNCTIONS  ///
157
    ////////////////////////
158
159
    /**
160
     * @param string $user
161
     *
162
     * @return FtpBuilder
163
     */
164
    public function setUser(string $user): self
165
    {
166
        $this->user = $user;
167
168
        return $this;
169
    }
170
171
    /**
172
     * @param string $password
173
     *
174
     * @return FtpBuilder
175
     */
176
    public function setPassword(string $password): self
177
    {
178
        $this->password = $password;
179
180
        return $this;
181
    }
182
183
    /**
184
     * @param string $host
185
     *
186
     * @return FtpBuilder
187
     */
188
    public function setHost(string $host): self
189
    {
190
        $this->host = $host;
191
192
        return $this;
193
    }
194
195
    /**
196
     * @param int $port
197
     *
198
     * @return FtpBuilder
199
     * @throws \LogicException
200
     */
201
    public function setPort(int $port): self
202
    {
203
        if (abs($port) !== $port) {
204
            throw new \LogicException('Ports cannot be negative');
205
        }
206
207
        $this->port = $port;
208
209
        return $this;
210
    }
211
212
    //////////////////////////////////
213
    /// INTERFACE IMPLEMENTATION  ///
214
    ////////////////////////////////
215
216
    /**
217
     * Returns all the components of the scheme including
218
     *  any bags in the form of an array
219
     *
220
     * @return array
221
     */
222
    public function all(): array
223
    {
224
        return [
225
            'scheme'   => self::SCHEME,
226
            'user'     => $this->user,
227
            'password' => $this->password,
228
            'host'     => $this->host,
229
            'port'     => -1 === $this->port ? '' : $this->port,
230
            'path'     => $this->pathBag->all(),
231
        ];
232
    }
233
234
    /**
235
     * Return the raw unaltered url
236
     *
237
     * @return string
238
     */
239
    public function raw(): string
240
    {
241
        return $this->build(false);
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    public function encoded(): string
248
    {
249
        return $this->build(true);
250
    }
251
252
    /**
253
     * Returns the scheme associated with the class
254
     *
255
     * @return string
256
     */
257
    public function getScheme(): string
258
    {
259
        return self::SCHEME;
260
    }
261
262
    /**
263
     * @param bool $urlEncode
264
     *
265
     * @return string
266
     */
267
    public function build(bool $urlEncode = false): string
268
    {
269
        // ftp://[user[:password]@]host[:port]/url-path
270
271
        $url = self::SCHEME.'://';
272
273
        if (!empty($this->user)) {
274
            $url .= $this->user;
275
            if (!empty($this->password)) {
276
                $url .= ':'.$this->password;
277
            }
278
279
            $url .= '@';
280
        }
281
282
        $url .= $this->host;
283
284
        if (-1 !== $this->port) {
285
            $url .= ':'.$this->port;
286
        }
287
288
        if ($urlEncode) {
289
            $url .= $this->pathBag->encoded();
290
        } else {
291
            $url .= $this->pathBag->raw();
292
        }
293
294
        return $url;
295
    }
296
}
297