Completed
Pull Request — master (#48)
by Frederik
05:48
created

Client::emit()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 12
cts 12
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 4
nop 1
crap 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol\Imap;
5
6
use Genkgo\Mail\Protocol\AppendCrlfConnection;
7
use Genkgo\Mail\Protocol\ConnectionInterface;
8
use Genkgo\Mail\Protocol\Imap\Negotiation\ReceiveWelcomeNegotiation;
9
use Genkgo\Mail\Protocol\Imap\Response\AggregateResponse;
10
use Genkgo\Mail\Stream\LineIterator;
11
12
final class Client
13
{
14
    public const AUTH_NONE = 0;
15
    
16
    public const AUTH_PLAIN = 1;
17
    
18
    public const AUTH_LOGIN = 2;
19
    
20
    public const AUTH_AUTO = 3;
21
22
    /**
23
     * @var ConnectionInterface
24
     */
25
    private $connection;
26
27
    /**
28
     * @var NegotiationInterface[]
29
     */
30
    private $negotiators = [];
31
32
    /**
33
     * @var TagFactoryInterface
34
     */
35
    private $tagFactory;
36
37
    /**
38
     * @param ConnectionInterface $connection
39
     * @param TagFactoryInterface $tagFactory
40
     * @param iterable $negotiators
41 23
     */
42
    public function __construct(
43
        ConnectionInterface $connection,
44
        TagFactoryInterface $tagFactory,
45
        iterable $negotiators = []
46 23
    ) {
47
        $this->connection = new AppendCrlfConnection($connection);
48 23
49
        $this->addNegotiator(new ReceiveWelcomeNegotiation($this->connection));
50 23
51 7
        foreach ($negotiators as $negotiator) {
52
            $this->addNegotiator($negotiator);
53
        }
54 23
55 4
        $this->connection->addListener('connect', function () {
56 4
            foreach ($this->negotiators as $negotiator) {
57
                $negotiator->negotiate($this);
58 23
            }
59
        });
60 23
61 23
        $this->tagFactory = $tagFactory;
62
    }
63
64
    /**
65
     * @param NegotiationInterface $negotiation
66 23
     */
67
    private function addNegotiator(NegotiationInterface $negotiation)
68 23
    {
69 23
        $this->negotiators[] = $negotiation;
70
    }
71
72
    /**
73
     * @param RequestInterface $request
74
     * @return AggregateResponse
75 17
     */
76
    public function emit(RequestInterface $request): AggregateResponse
77 17
    {
78 17
        $stream = $request->toStream();
79
80 17
        foreach (new LineIterator($stream) as $line) {
81 17
            $this->connection->send($line);
82 17
        }
83
84 17
        $response = new AggregateResponse($request->getTag());
85 17
86 17
        while (!$response->hasCompleted()) {
87 2
            $response = $response->withLine($this->connection->receive());
88 2
        }
89 2
90
        return $response;
91 2
    }
92
93
    /**
94 17
     * @return Tag
95
     */
96
    public function newTag(): Tag
97
    {
98 17
        return $this->tagFactory->newTag();
99
    }
100
}
101