Completed
Push — master ( 503b9d...92f54d )
by Frederik
03:38
created

ClientFactory::fromString()   C

Complexity

Conditions 13
Paths 82

Size

Total Lines 69
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 46
CRAP Score 13

Importance

Changes 0
Metric Value
dl 0
loc 69
rs 5.6955
c 0
b 0
f 0
ccs 46
cts 46
cp 1
cc 13
eloc 47
nc 82
nop 1
crap 13

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Smtp;
5
6
use Genkgo\Mail\Protocol\ConnectionInterface;
7
use Genkgo\Mail\Protocol\PlainTcpConnection;
8
use Genkgo\Mail\Protocol\SecureConnectionOptions;
9
use Genkgo\Mail\Protocol\Smtp\Negotiation\AuthNegotiation;
10
use Genkgo\Mail\Protocol\Smtp\Negotiation\ConnectionNegotiation;
11
use Genkgo\Mail\Protocol\SslConnection;
12
use Genkgo\Mail\Protocol\TlsConnection;
13
14
/**
15
 * Class ClientFactory
16
 * @package Genkgo\Mail\Protocol\Smtp
17
 */
18
final class ClientFactory
19
{
20
    /**
21
     *
22
     */
23
    private CONST AUTH_ENUM = [Client::AUTH_NONE, Client::AUTH_PLAIN, Client::AUTH_LOGIN, Client::AUTH_AUTO];
24
    /**
25
     * @var ConnectionInterface
26
     */
27
    private $connection;
28
    /**
29
     * @var string
30
     */
31
    private $password = '';
32
    /**
33
     * @var float
34
     */
35
    private $timeout = 1;
36
    /**
37
     * @var string
38
     */
39
    private $username = '';
40
    /**
41
     * @var string
42
     */
43
    private $ehlo = '127.0.0.1';
44
    /**
45
     * @var int
46
     */
47
    private $authMethod = Client::AUTH_NONE;
48
    /**
49
     * @var bool
50
     */
51
    private $insecureAllowed = false;
52
53
    /**
54
     * ClientFactory constructor.
55
     * @param ConnectionInterface $connection
56
     */
57 8
    public function __construct(ConnectionInterface $connection)
58
    {
59 8
        $this->connection = $connection;
60 8
    }
61
62
    /**
63
     * @param float $connectionTimeout
64
     * @return ClientFactory
65
     */
66 2
    public function withTimeout(float $connectionTimeout): ClientFactory
67
    {
68 2
        $clone = clone $this;
69 2
        $clone->timeout = $connectionTimeout;
70 2
        return $clone;
71
    }
72
73
    /**
74
     * @param int $method
75
     * @param string $password
76
     * @param string $username
77
     * @return ClientFactory
78
     */
79 4
    public function withAuthentication(int $method, string $username, string $password): ClientFactory
80
    {
81 4
        if (!in_array($method, self::AUTH_ENUM)) {
82 1
            throw new \InvalidArgumentException('Invalid authentication method');
83
        }
84
85 3
        $clone = clone $this;
86 3
        $clone->authMethod = $method;
87 3
        $clone->username = $username;
88 3
        $clone->password = $password;
89 3
        return $clone;
90
    }
91
92
    /**
93
     * @param string $ehlo
94
     * @return ClientFactory
95
     */
96 3
    public function withEhlo(string $ehlo): ClientFactory
97
    {
98 3
        $clone = clone $this;
99 3
        $clone->ehlo = $ehlo;
100 3
        return $clone;
101
    }
102
103
    /**
104
     * @return ClientFactory
105
     */
106 3
    public function withAllowInsecure(): ClientFactory
107
    {
108 3
        $clone = clone $this;
109 3
        $clone->insecureAllowed = true;
110 3
        return $clone;
111
    }
112
113
    /**
114
     * @return Client
115
     */
116 6
    public function newClient(): Client
117
    {
118
        $negotiators = [
119 6
            new ConnectionNegotiation(
120 6
                $this->connection,
121 6
                $this->ehlo,
122 6
                $this->insecureAllowed
123
            )
124
        ];
125
126 6
        if ($this->authMethod !== Client::AUTH_NONE) {
127 2
            $negotiators[] = new AuthNegotiation(
128 2
                $this->ehlo,
129 2
                $this->authMethod,
130 2
                $this->username,
131 2
                $this->password
132
            );
133
        }
134
135 6
        return new Client($this->connection, $negotiators);
136
    }
137
138
    /**
139
     * @param string $dataSourceName
140
     * @return ClientFactory
141
     */
142 6
    public static function fromString(string $dataSourceName):ClientFactory
143
    {
144 6
        $components = parse_url($dataSourceName);
145 6
        if (!isset($components['scheme']) || !isset($components['host'])) {
146 1
            throw new \InvalidArgumentException('Scheme and host are required');
147
        }
148
149 5
        $allowInsecure = false;
150 5
        switch ($components['scheme']) {
151 5
            case 'smtp+tls':
152 1
                $connection = new TlsConnection(
153 1
                    $components['host'],
154 1
                    $components['port'] ?? 465,
155 1
                    new SecureConnectionOptions()
156
                );
157 1
                break;
158 4
            case 'smtp+ssl':
159 1
                $connection = new SslConnection(
160 1
                    $components['host'],
161 1
                    $components['port'] ?? 465,
162 1
                    new SecureConnectionOptions()
163
                );
164 1
                break;
165 3
            case 'smtp+plain':
166 1
                $allowInsecure = true;
167 1
                $connection = new PlainTcpConnection(
168 1
                    $components['host'],
169 1
                    $components['port'] ?? 25
170
                );
171 1
                break;
172 2
            case 'smtp':
173 1
                $connection = new PlainTcpConnection(
174 1
                    $components['host'],
175 1
                    $components['port'] ?? 587
176
                );
177 1
                break;
178
            default:
179 1
                throw new \InvalidArgumentException(
180 1
                    'Use smtp:// smtp+tls:// smtp+ssl:// smtp+plain://'
181
                );
182
        }
183
184 4
        $factory = new self($connection);
185 4
        if ($allowInsecure) {
186 1
            $factory = $factory->withAllowInsecure();
187
        }
188
189 4
        if (isset($components['user']) && isset($components['pass'])) {
190 1
            $factory = $factory->withAuthentication(
191 1
                Client::AUTH_AUTO,
192 1
                urldecode($components['user']),
193 1
                urldecode($components['pass'])
194
            );
195
        }
196
197 4
        if (isset($components['query'])) {
198 1
            parse_str($components['query'], $query);
199
200 1
            if (isset($query['ehlo'])) {
201 1
                $factory = $factory->withEhlo($query['ehlo']);
202
            }
203
204 1
            if (isset($query['timeout'])) {
205 1
                $factory = $factory->withTimeout((float)$query['timeout']);
206
            }
207
        }
208
209 4
        return $factory;
210
    }
211
}
212