Completed
Pull Request — master (#40)
by
unknown
08:46
created

ServersArePingable::parseConfiguredServers()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8657
c 0
b 0
f 0
cc 6
nc 6
nop 1
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
    /**
18
     * The name of the check.
19
     *
20
     * @param array $config
21
     * @return string
22
     */
23
    public function name(array $config): string
24
    {
25
        return trans('self-diagnosis::checks.servers_are_pingable.name');
26
    }
27
28
    /**
29
     * Perform the actual verification of this check.
30
     *
31
     * @param array $config
32
     * @return bool
33
     * @throws InvalidConfigurationException
34
     */
35
    public function check(array $config): bool
36
    {
37
        $this->notReachableServers = $this->parseConfiguredServers(array_get($config, 'servers', []));
38
        if ($this->notReachableServers->isEmpty()) {
39
            return true;
40
        }
41
42
        $this->notReachableServers = $this->notReachableServers->reject(function (Server $server) {
43
            $ping = new Ping($server->getHost());
44
            $ping->setPort($server->getPort());
45
            $ping->setTimeout($server->getTimeout());
46
47
            if ($ping->getPort() === null) {
48
                $latency = $ping->ping('exec');
49
            } else {
50
                $latency = $ping->ping('fsockopen');
51
            }
52
53
            return $latency !== false;
54
        });
55
56
        return $this->notReachableServers->isEmpty();
57
    }
58
59
    /**
60
     * The error message to display in case the check does not pass.
61
     *
62
     * @param array $config
63
     * @return string
64
     */
65
    public function message(array $config): string
66
    {
67
        return $this->notReachableServers->map(function (Server $server) {
68
            return trans('self-diagnosis::checks.servers_are_pingable.message', [
69
                'host' => $server->getHost(),
70
                'port' => $server->getPort() ?? 'n/a',
71
                'timeout' => $server->getTimeout(),
72
            ]);
73
        })->implode(PHP_EOL);
74
    }
75
76
    /**
77
     * Parses an array of servers which can be given in different formats.
78
     * Unifies the format for the resulting collection.
79
     *
80
     * @param array $servers
81
     * @return Collection
82
     * @throws InvalidConfigurationException
83
     */
84
    private function parseConfiguredServers(array $servers): Collection
85
    {
86
        $result = new Collection();
87
88
        foreach ($servers as $server) {
89
            if (is_array($server)) {
90
                if (!empty(array_except($server, ['host', 'port', 'timeout']))) {
91
                    throw new InvalidConfigurationException('Servers in array notation may only contain a host, port and timeout parameter.');
92
                }
93
                if (!array_has($server, 'host')) {
94
                    throw new InvalidConfigurationException('For servers in array notation, the host parameter is required.');
95
                }
96
97
                $host = array_get($server, 'host');
98
                $port = array_get($server, 'port');
99
                $timeout = array_get($server, 'timeout', self::DEFAULT_TIMEOUT);
100
101
                $result->push(new Server($host, $port, $timeout));
102
            } else if (is_string($server)) {
103
                $result->push(new Server($server, null, self::DEFAULT_TIMEOUT));
104
            } else {
105
                throw new InvalidConfigurationException('The server configuration may only contain arrays or strings.');
106
            }
107
        }
108
109
        return $result;
110
    }
111
}
112