Completed
Push — master ( 79ff26...9e9048 )
by Niels
02:04
created

DirectAdmin::invokeApi()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 3
1
<?php
2
3
/*
4
 * DirectAdmin API Client
5
 * (c) Omines Internetbureau B.V. - https://omines.nl/
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Omines\DirectAdmin;
12
13
use GuzzleHttp\Client;
14
use GuzzleHttp\Exception\TransferException;
15
use Omines\DirectAdmin\Context\AdminContext;
16
use Omines\DirectAdmin\Context\ResellerContext;
17
use Omines\DirectAdmin\Context\UserContext;
18
use Omines\DirectAdmin\Utility\Conversion;
19
20
/**
21
 * DirectAdmin API main class, encapsulating a specific account connection to a single server.
22
 *
23
 * @author Niels Keurentjes <[email protected]>
24
 */
25
class DirectAdmin
26
{
27
    const ACCOUNT_TYPE_ADMIN = 'admin';
28
    const ACCOUNT_TYPE_RESELLER = 'reseller';
29
    const ACCOUNT_TYPE_USER = 'user';
30
31
    /** @var string */
32
    private $authenticatedUser;
33
34
    /** @var string */
35
    private $username;
36
37
    /** @var string */
38
    private $password;
39
40
    /** @var string */
41
    private $baseUrl;
42
43
    /** @var Client */
44
    private $connection;
45
46
    /**
47
     * Connects to DirectAdmin with an admin account.
48
     *
49
     * @param string $url The base URL of the DirectAdmin server
50
     * @param string $username The username of the account
51
     * @param string $password The password of the account
52
     * @param bool $validate Whether to ensure the account exists and is of the correct type
53
     * @return AdminContext
54
     */
55
    public static function connectAdmin($url, $username, $password, $validate = false)
56
    {
57
        return new AdminContext(new self($url, $username, $password), $validate);
58
    }
59
60
    /**
61
     * Connects to DirectAdmin with a reseller account.
62
     *
63
     * @param string $url The base URL of the DirectAdmin server
64
     * @param string $username The username of the account
65
     * @param string $password The password of the account
66
     * @param bool $validate Whether to ensure the account exists and is of the correct type
67
     * @return ResellerContext
68
     */
69
    public static function connectReseller($url, $username, $password, $validate = false)
70
    {
71
        return new ResellerContext(new self($url, $username, $password), $validate);
72
    }
73
74
    /**
75
     * Connects to DirectAdmin with a user account.
76
     *
77
     * @param string $url The base URL of the DirectAdmin server
78
     * @param string $username The username of the account
79
     * @param string $password The password of the account
80
     * @param bool $validate Whether to ensure the account exists and is of the correct type
81
     * @return UserContext
82
     */
83
    public static function connectUser($url, $username, $password, $validate = false)
84
    {
85
        return new UserContext(new self($url, $username, $password), $validate);
86
    }
87
88
    /**
89
     * Creates a connection wrapper to DirectAdmin as the specified account.
90
     *
91
     * @param string $url The base URL of the DirectAdmin server
92
     * @param string $username The username of the account
93
     * @param string $password The password of the account
94
     */
95
    protected function __construct($url, $username, $password)
96
    {
97
        $accounts = explode('|', $username);
98
        $this->authenticatedUser = current($accounts);
99
        $this->username = end($accounts);
100
        $this->password = $password;
101
        $this->baseUrl = rtrim($url, '/') . '/';
102
        $this->connection = new Client([
103
            'base_uri' => $this->baseUrl,
104
            'auth' => [$username, $password],
105
        ]);
106
    }
107
108
    /**
109
     * Returns the username behind the current connection.
110
     *
111
     * @return string Currently logged in user's username
112
     */
113
    public function getUsername()
114
    {
115
        return $this->username;
116
    }
117
118
    /**
119
     * Invokes the DirectAdmin API with specific options.
120
     *
121
     * @param string $method HTTP method to use (ie. GET or POST)
122
     * @param string $command DirectAdmin API command to invoke
123
     * @param array $options Guzzle options to use for the call
124
     * @return array The unvalidated response
125
     * @throws DirectAdminException If anything went wrong on the network level
126
     */
127
    public function invokeApi($method, $command, $options = [])
128
    {
129
        $result = $this->rawRequest($method, '/CMD_API_' . $command, $options);
130
        if (!empty($result['error'])) {
131
            throw new DirectAdminException("$method to $command failed: $result[details] ($result[text])");
132
        }
133
        return Conversion::sanitizeArray($result);
134
    }
135
136
    /**
137
     * Returns a clone of the connection logged in as a managed user or reseller.
138
     *
139
     * @param string $username
140
     * @return DirectAdmin
141
     */
142
    public function loginAs($username)
143
    {
144
        // DirectAdmin format is to just pipe the accounts together under the master password
145
        return new self($this->baseUrl, $this->authenticatedUser . "|{$username}", $this->password);
146
    }
147
148
    /**
149
     * Sends a raw request to DirectAdmin.
150
     *
151
     * @param string $method
152
     * @param string $uri
153
     * @param array $options
154
     * @return array
155
     */
156
    private function rawRequest($method, $uri, $options)
157
    {
158
        try {
159
            $response = $this->connection->request($method, $uri, $options);
160
            if ($response->getHeader('Content-Type')[0] == 'text/html') {
161
                throw new DirectAdminException(sprintf('DirectAdmin API returned text/html to %s %s containing "%s"', $method, $uri, strip_tags($response->getBody()->getContents())));
162
            }
163
            $body = $response->getBody()->getContents();
164
            return Conversion::responseToArray($body);
165
        } catch (TransferException $exception) {
166
            // Rethrow anything that causes a network issue
167
            throw new DirectAdminException(sprintf('%s request to %s failed', $method, $uri), 0, $exception);
168
        }
169
    }
170
}
171