Completed
Push — master ( b67977...b30551 )
by Timur
03:20
created

Forge::setRateLimiter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Laravel\Forge;
4
5
use Iterator;
6
use ArrayAccess;
7
use GuzzleHttp\ClientInterface;
8
use Laravel\Forge\Servers\Factory;
9
use Laravel\Forge\Traits\LazyIterator;
10
use Laravel\Forge\Traits\LazyArrayAccess;
11
use GuzzleHttp\Exception\RequestException;
12
use Laravel\Forge\Traits\AbstractCollection;
13
use Laravel\Forge\Contracts\ResourceContract;
14
use Laravel\Forge\Exceptions\Servers\ServerWasNotFoundException;
15
16
class Forge implements ArrayAccess, Iterator, ResourceContract
17
{
18
    use AbstractCollection, LazyIterator, LazyArrayAccess;
19
20
    /**
21
     * API provider.
22
     *
23
     * @var \Laravel\Forge\ApiProvider
24
     */
25
    protected $api;
26
27
    /**
28
     * Servers [id => name] map.
29
     *
30
     * @var array
31
     */
32
    protected $serversMap = [];
33
34
    /**
35
     * Single servers cache.
36
     *
37
     * @var array
38
     */
39
    protected $serversCache = [];
40
41
    /**
42
     * Create new Servers manager instance.
43
     *
44
     * @param \Laravel\Forge\ApiProvider $api
45
     */
46
    public function __construct(ApiProvider $api)
47
    {
48
        $this->api = $api;
49
    }
50
51
    /**
52
     * Get API provider.
53
     *
54
     * @return \Laravel\Forge\ApiProvider
55
     */
56
    public function getApi(): ApiProvider
57
    {
58
        return $this->api;
59
    }
60
61
    /**
62
     * Get underlying API provider's HTTP client.
63
     *
64
     * @return \GuzzleHttp\ClientInterface
65
     */
66
    public function getHttpClient(): ClientInterface
67
    {
68
        return $this->api->getClient();
69
    }
70
71
    /**
72
     * Resource API URL.
73
     *
74
     * @param string $path            = ''
75
     * @param bool   $withPropagation = true
76
     *
77
     * @return string
78
     */
79
    public function apiUrl(string $path = '', bool $withPropagation = true): string
80
    {
81
        return $path;
82
    }
83
84
    /**
85
     * Resource name.
86
     *
87
     * @return string
88
     */
89
    public function name()
90
    {
91
        return 'forge';
92
    }
93
94
    /**
95
     * @{inheritdocs}
96
     */
97
    public function lazyLoad()
98
    {
99
        $response = $this->api->getClient()->request('GET', 'servers');
100
        $data = json_decode((string) $response->getBody(), true);
101
102
        $this->items = [];
103
        $this->serversMap = [];
104
105
        if (empty($data['servers'])) {
106
            return $this->items;
107
        }
108
109
        foreach ($data['servers'] as $server) {
110
            $this->items[$server['name']] = new Server($this->api, $server);
111
            $this->serversMap[$server['id']] = $server['name'];
112
        }
113
114
        return $this->items;
115
    }
116
117
    /**
118
     * Generate items keys.
119
     */
120
    public function generateKeys()
121
    {
122
        $this->keys = array_keys($this->items);
123
    }
124
125
    /**
126
     * Initialize servers factory.
127
     *
128
     * @return \Laravel\Forge\Servers\Factory
129
     */
130
    public function create()
131
    {
132
        return new Factory($this->api);
133
    }
134
135
    /**
136
     * Returns single server.
137
     *
138
     * @param int  $serverId
139
     * @param bool $reload   (optional) indicates whether the server should be reloaded
140
     *
141
     * @return \Laravel\Forge\Server
142
     */
143
    public function get(int $serverId, bool $reload = false)
144
    {
145
        if ($reload === true) {
146
            return $this->loadSingleServer($serverId);
147
        }
148
149
        if ($this->lazyLoadInitiated() && isset($this->serversMap[$serverId])) {
150
            return $this->items[$this->serversMap[$serverId]];
151
        } elseif (isset($this->serversCache[$serverId])) {
152
            return $this->serversCache[$serverId];
153
        }
154
155
        return $this->loadSingleServer($serverId);
156
    }
157
158
    /**
159
     * Get server provider credentials.
160
     *
161
     * @return array
162
     */
163
    public function credentials(): array
164
    {
165
        $response = $this->api->getClient()->request('GET', 'credentials');
166
        $json = json_decode((string) $response->getBody(), true);
167
168
        if (empty($json['credentials'])) {
169
            return [];
170
        }
171
172
        return $json['credentials'];
173
    }
174
175
    /**
176
     * Get first credential for given provider.
177
     *
178
     * @param string $provider
179
     *
180
     * @return int|null
181
     */
182
    public function credentialFor(string $provider)
183
    {
184
        $credentials = $this->credentials();
185
186
        if (!count($credentials)) {
187
            return;
188
        }
189
190
        foreach ($credentials as $credential) {
191
            if ($credential['type'] === $provider) {
192
                return intval($credential['id']);
193
            }
194
        }
195
    }
196
197
    /**
198
     * Load single server from API and save it to memory cache.
199
     *
200
     * @param int $serverId
201
     *
202
     * @throws \Laravel\Forge\Exceptions\Servers\ServerWasNotFoundException
203
     *
204
     * @return \Laravel\Forge\Server
205
     */
206
    protected function loadSingleServer(int $serverId)
207
    {
208
        try {
209
            $response = $this->api->getClient()->request('GET', 'servers/'.$serverId);
210
        } catch (RequestException $e) {
211
            if ($e->getResponse()->getStatusCode() === 404) {
212
                throw new ServerWasNotFoundException('Server #'.$serverId.' was not found.', 404);
213
            }
214
215
            throw $e;
216
        }
217
218
        return $this->serversCache[$serverId] = Server::createFromResponse($response, $this->api);
219
    }
220
221
    /**
222
     * Sets an optional rate limiting function on the api provider.
223
     *
224
     * @param callable $rateLimiter
225
     */
226
    public function setRateLimiter(callable $rateLimiter)
227
    {
228
        $this->api->setRateLimiter($rateLimiter);
229
    }
230
}
231