Completed
Pull Request — master (#60)
by
unknown
177:15
created

ServersArePingable   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 0
loc 107
ccs 42
cts 42
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A name() 0 4 1
A check() 0 23 3
A message() 0 10 1
B parseConfiguredServers() 0 27 6
1
<?php
2
3
namespace BeyondCode\SelfDiagnosis\Checks;
4
5
use BeyondCode\SelfDiagnosis\Exceptions\InvalidConfigurationException;
6
use BeyondCode\SelfDiagnosis\Server;
7
use Illuminate\Support\Collection;
8
use JJG\Ping;
9
10
class ServersArePingable implements Check
11
{
12
    protected const DEFAULT_TIMEOUT = 5;
13
14
    /** @var Collection */
15
    protected $notReachableServers;
16
17 44
    public function __construct()
18
    {
19 44
        $this->notReachableServers = new Collection();
20 44
    }
21
22
    /**
23
     * The name of the check.
24
     *
25
     * @param array $config
26
     * @return string
27
     */
28 4
    public function name(array $config): string
29
    {
30 4
        return trans('self-diagnosis::checks.servers_are_pingable.name');
31
    }
32
33
    /**
34
     * Perform the actual verification of this check.
35
     *
36
     * @param array $config
37
     * @return bool
38
     * @throws InvalidConfigurationException
39
     */
40 36
    public function check(array $config): bool
41
    {
42 36
        $this->notReachableServers = $this->parseConfiguredServers(array_get($config, 'servers', []));
43 24
        if ($this->notReachableServers->isEmpty()) {
44 4
            return true;
45
        }
46
47 10
        $this->notReachableServers = $this->notReachableServers->reject(function (Server $server) {
48 20
            $ping = new Ping($server->getHost());
49 20
            $ping->setPort($server->getPort());
50 20
            $ping->setTimeout($server->getTimeout());
51
52 20
            if ($ping->getPort() === null) {
53 16
                $latency = $ping->ping('exec');
54
            } else {
55 4
                $latency = $ping->ping('fsockopen');
56
            }
57
58 20
            return $latency !== false;
59 20
        });
60
61 20
        return $this->notReachableServers->isEmpty();
62
    }
63
64
    /**
65
     * The error message to display in case the check does not pass.
66
     *
67
     * @param array $config
68
     * @return string
69
     */
70 6
    public function message(array $config): string
71
    {
72 6
        return $this->notReachableServers->map(function (Server $server) {
73 8
            return trans('self-diagnosis::checks.servers_are_pingable.message', [
74 8
                'host' => $server->getHost(),
75 8
                'port' => $server->getPort() ?? 'n/a',
76 8
                'timeout' => $server->getTimeout(),
77
            ]);
78 12
        })->implode(PHP_EOL);
79
    }
80
81
    /**
82
     * Parses an array of servers which can be given in different formats.
83
     * Unifies the format for the resulting collection.
84
     *
85
     * @param array $servers
86
     * @return Collection
87
     * @throws InvalidConfigurationException
88
     */
89 36
    private function parseConfiguredServers(array $servers): Collection
90
    {
91 36
        $result = new Collection();
92
93 36
        foreach ($servers as $server) {
94 32
            if (is_array($server)) {
95 24
                if (!empty(array_except($server, ['host', 'port', 'timeout']))) {
96 4
                    throw new InvalidConfigurationException('Servers in array notation may only contain a host, port and timeout parameter.');
97
                }
98 20
                if (!array_has($server, 'host')) {
99 4
                    throw new InvalidConfigurationException('For servers in array notation, the host parameter is required.');
100
                }
101
102 16
                $host = array_get($server, 'host');
103 16
                $port = array_get($server, 'port');
104 16
                $timeout = array_get($server, 'timeout', self::DEFAULT_TIMEOUT);
105
106 16
                $result->push(new Server($host, $port, $timeout));
107 8
            } else if (is_string($server)) {
108 4
                $result->push(new Server($server, null, self::DEFAULT_TIMEOUT));
109
            } else {
110 24
                throw new InvalidConfigurationException('The server configuration may only contain arrays or strings.');
111
            }
112
        }
113
114 24
        return $result;
115
    }
116
}
117