Server::getSshConnectionString()   B
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 7
nc 2
nop 0
dl 0
loc 11
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
4
namespace Bencagri\Artisan\Deployer\Server;
5
6
use Bencagri\Artisan\Deployer\Exception\ServerConfigurationException;
7
use Bencagri\Artisan\Deployer\Helper\Str;
8
use Symfony\Component\HttpFoundation\ParameterBag;
9
10
class Server
11
{
12
    const ROLE_APP = 'app';
13
    private const LOCALHOST_ADDRESSES = ['localhost', 'local', '127.0.0.1'];
14
    private $roles;
15
    private $user;
16
    private $host;
17
    private $port;
18
    private $properties;
19
20
    public function __construct(string $dsn, array $roles = [self::ROLE_APP], array $properties = [])
21
    {
22
        $this->roles = $roles;
23
        $this->properties = new ParameterBag($properties);
24
25
        // add the 'ssh://' scheme so the URL parsing works as expected
26
        $params = parse_url(Str::startsWith($dsn, 'ssh://') ? $dsn : 'ssh://'.$dsn);
27
28
        $this->user = $params['user'] ?? null;
29
30
        if (!isset($params['host'])) {
31
            throw new ServerConfigurationException($dsn, 'The host is missing (define it as an IP address or a host name)');
32
        }
33
        $this->host = $params['host'];
34
35
        $this->port = $params['port'] ?? null;
36
    }
37
38
    public function __toString() : string
39
    {
40
        return sprintf('%s%s', $this->getUser() ? $this->getUser().'@' : '', $this->getHost());
41
    }
42
43
    public function isLocalHost() : bool
44
    {
45
        return in_array($this->getHost(), self::LOCALHOST_ADDRESSES, true);
46
    }
47
48
    public function resolveProperties(string $expression) : string
49
    {
50
        $definedProperties = $this->properties;
51
        $resolved = preg_replace_callback('/(\{\{\s*(?<propertyName>.+)\s*\}\})/U', function (array $matches) use ($definedProperties, $expression) {
52
            $propertyName = trim($matches['propertyName']);
53
            if (!$definedProperties->has($propertyName)) {
54
                throw new \InvalidArgumentException(sprintf('The "%s" property in "%s" expression is not a valid server property.', $propertyName, $expression));
55
            }
56
57
            return $definedProperties->get($propertyName);
58
        }, $expression);
59
60
        return $resolved;
61
    }
62
63
    public function getProperties() : array
64
    {
65
        return $this->properties->all();
66
    }
67
68
    public function get(string $propertyName, $default = null)
69
    {
70
        return $this->properties->get($propertyName, $default);
71
    }
72
73
    public function set(string $propertyName, $value) : void
74
    {
75
        $this->properties->set($propertyName, $value);
76
    }
77
78
    public function has(string $propertyName) : bool
79
    {
80
        return $this->properties->has($propertyName);
81
    }
82
83
    public function getSshConnectionString() : string
84
    {
85
        if ($this->isLocalHost()) {
86
            return '';
87
        }
88
89
        return sprintf('ssh %s%s%s%s',
90
            $this->properties->get('use_ssh_agent_forwarding') ? '-A ' : '',
91
            $this->user ?? '',
92
            $this->user ? '@'.$this->host : $this->host,
93
            $this->port ? ' -p '.$this->port : ''
94
        );
95
    }
96
97
    public function getRoles() : array
98
    {
99
        return $this->roles;
100
    }
101
102
    public function getUser() : ?string
103
    {
104
        return $this->user;
105
    }
106
107
    public function getHost() : string
108
    {
109
        return $this->host;
110
    }
111
112
    public function getPort() : ?int
113
    {
114
        return $this->port;
115
    }
116
}
117