Completed
Push — master ( 3ff097...503b9d )
by Frederik
06:54
created

AbstractConnection::send()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Protocol;
5
6
/**
7
 * Class AbstractConnection
8
 * @package Genkgo\Mail\Protocol
9
 * @codeCoverageIgnore
10
 */
11
abstract class AbstractConnection implements ConnectionInterface
12
{
13
    /**
14
     *
15
     */
16
    private const RECEIVE_BYTES = 1024;
17
    /**
18
     * @var resource
19
     */
20
    protected $resource;
21
22
    /**
23
     *
24
     */
25
    final public function __destruct()
26
    {
27
        $this->disconnect();
28
    }
29
30
    /**
31
     *
32
     */
33
    abstract public function connect(): void;
34
35
    /**
36
     *
37
     */
38
    final public function disconnect(): void
39
    {
40
        fclose($this->resource);
41
        $this->resource = null;
42
    }
43
44
    /**
45
     * @param float $timeout
46
     */
47
    final public function timeout(float $timeout): void
48
    {
49
        stream_set_timeout($this->resource, $timeout);
50
    }
51
52
    /**
53
     * @param string $request
54
     * @return int
55
     */
56
    final public function send(string $request): int
57
    {
58
        $this->verifyConnection();
59
60
        $bytesWritten = fwrite($this->resource, $request);
61
62
        if ($bytesWritten === false) {
63
            throw new \RuntimeException(sprintf('Could not send command:'));
64
        }
65
66
        $this->verifyAlive();
67
68
        return $bytesWritten;
69
    }
70
71
    /**
72
     * @return string
73
     */
74
    final public function receive(): string
75
    {
76
        $this->verifyConnection();
77
78
        $response = fgets($this->resource, self::RECEIVE_BYTES);
79
80
        $this->verifyAlive();
81
82
        return $response;
83
    }
84
85
    /**
86
     *
87
     */
88
    private function verifyConnection()
89
    {
90
        if (!is_resource($this->resource)) {
91
            throw new \RuntimeException('Cannot send/receive data while not connected');
92
        }
93
    }
94
95
    /**
96
     *
97
     */
98
    private function verifyAlive()
99
    {
100
        $info = stream_get_meta_data($this->resource);
101
        if ($info['timed_out']) {
102
            throw new \RuntimeException('Connection has timed out');
103
        }
104
    }
105
}