Passed
Push — master ( 75c8cb...bd66d8 )
by Artem
11:55
created

LinodeClient::api()   B

Complexity

Conditions 10
Paths 82

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 10

Importance

Changes 0
Metric Value
cc 10
eloc 16
c 0
b 0
f 0
nc 82
nop 4
dl 0
loc 29
ccs 19
cts 19
cp 1
crap 10
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
//----------------------------------------------------------------------
4
//
5
//  Copyright (C) 2018 Artem Rodygin
6
//
7
//  You should have received a copy of the MIT License along with
8
//  this file. If not, see <http://opensource.org/licenses/MIT>.
9
//
10
//----------------------------------------------------------------------
11
12
namespace Linode;
13
14
use GuzzleHttp\Client;
15
use GuzzleHttp\Exception\ClientException;
16
use GuzzleHttp\Exception\GuzzleException;
17
use GuzzleHttp\Psr7\Response;
18
use Linode\Entity\Account;
19
use Linode\Entity\Profile;
20
use Linode\Exception\LinodeException;
21
use Linode\Internal\Domains\DomainRepository;
22
use Linode\Internal\ImageRepository;
23
use Linode\Internal\KernelRepository;
24
use Linode\Internal\LinodeRepository;
25
use Linode\Internal\LinodeTypeRepository;
26
use Linode\Internal\Longview\LongviewSubscriptionRepository;
27
use Linode\Internal\Networking\IPAddressRepository;
28
use Linode\Internal\Networking\IPv6PoolRepository;
29
use Linode\Internal\Networking\IPv6RangeRepository;
30
use Linode\Internal\NodeBalancers\NodeBalancerRepository;
31
use Linode\Internal\RegionRepository;
32
use Linode\Internal\StackScriptRepository;
33
use Linode\Internal\Support\SupportTicketRepository;
34
use Linode\Internal\Tags\TagRepository;
35
use Linode\Internal\VolumeRepository;
36
use Psr\Http\Message\ResponseInterface;
37
38
/**
39
 * Linode API client.
40
 *
41
 * @property Entity\Account                                              $account
42
 * @property Repository\Domains\DomainRepositoryInterface                $domains
43
 * @property Repository\ImageRepositoryInterface                         $images
44
 * @property Repository\Networking\IPAddressRepositoryInterface          $ips
45
 * @property Repository\Networking\IPv6PoolRepositoryInterface           $ipv6_pools
46
 * @property Repository\Networking\IPv6RangeRepositoryInterface          $ipv6_ranges
47
 * @property Repository\KernelRepositoryInterface                        $kernels
48
 * @property Repository\LinodeRepositoryInterface                        $linodes
49
 * @property Repository\LinodeTypeRepositoryInterface                    $linode_types
50
 * @property Repository\Longview\LongviewSubscriptionRepositoryInterface $longview_subscriptions
51
 * @property Repository\NodeBalancers\NodeBalancerRepositoryInterface    $node_balancers
52
 * @property Entity\Profile                                              $profile
53
 * @property Repository\RegionRepositoryInterface                        $regions
54
 * @property Repository\StackScriptRepositoryInterface                   $stackscripts
55
 * @property Repository\Tags\TagRepositoryInterface                      $tags
56
 * @property Repository\Support\SupportTicketRepositoryInterface         $tickets
57
 * @property Repository\VolumeRepositoryInterface                        $volumes
58
 */
59
class LinodeClient
60
{
61
    // Request methods.
62
    public const REQUEST_GET    = 'GET';
63
    public const REQUEST_POST   = 'POST';
64
    public const REQUEST_PUT    = 'PUT';
65
    public const REQUEST_DELETE = 'DELETE';
66
67
    // Base URI to Linode API.
68
    protected const BASE_API_URI = 'https://api.linode.com/v4';
69
70
    /** @var Client HTTP client. */
71
    protected Client $client;
72
73
    /**
74
     * LinodeClient constructor.
75
     *
76
     * @param null|string $access_token API access token (PAT or retrieved via OAuth)
77
     */
78
    public function __construct(protected ?string $access_token = null)
79
    {
80
        $this->client = new Client();
81 252
    }
82
83 252
    /**
84 252
     * Returns specified repository.
85 252
     *
86
     * @param string $name repository name
87
     */
88
    public function __get(string $name): null|Account|Profile|Repository\RepositoryInterface
89
    {
90
        return match ($name) {
91
            'account'                => new Account($this),
92
            'domains'                => new DomainRepository($this),
93
            'images'                 => new ImageRepository($this),
94 1
            'ips'                    => new IPAddressRepository($this),
95
            'ipv6_pools'             => new IPv6PoolRepository($this),
96
            'ipv6_ranges'            => new IPv6RangeRepository($this),
97
            'kernels'                => new KernelRepository($this),
98 1
            'linodes'                => new LinodeRepository($this),
99 1
            'linode_types'           => new LinodeTypeRepository($this),
100
            'longview_subscriptions' => new LongviewSubscriptionRepository($this),
101 1
            'node_balancers'         => new NodeBalancerRepository($this),
102 1
            'profile'                => new Profile($this),
103
            'regions'                => new RegionRepository($this),
104 1
            'stackscripts'           => new StackScriptRepository($this),
105 1
            'tags'                   => new TagRepository($this),
106
            'tickets'                => new SupportTicketRepository($this),
107 1
            'volumes'                => new VolumeRepository($this),
108 1
            default                  => null,
109
        };
110 1
    }
111 1
112
    /**
113 1
     * Performs a request to specified API endpoint.
114 1
     *
115
     * @param string $method     request method
116 1
     * @param string $uri        relative URI to API endpoint
117 1
     * @param array  $parameters optional parameters
118
     * @param array  $filters    optional filters
119 1
     *
120 1
     * @throws LinodeException
121
     */
122 1
    public function api(string $method, string $uri, array $parameters = [], array $filters = []): ResponseInterface
123 1
    {
124
        try {
125 1
            $options = [];
126 1
127
            if ($this->access_token !== null) {
128 1
                $options['headers']['Authorization'] = 'Bearer ' . $this->access_token;
129 1
            }
130
131 1
            if (count($filters) !== 0 && $method === self::REQUEST_GET) {
132 1
                $options['headers']['X-Filter'] = json_encode($filters);
133
            }
134 1
135 1
            if (count($parameters) !== 0) {
136
                if ($method === self::REQUEST_GET) {
137 1
                    $options['query'] = $parameters;
138 1
                }
139
                elseif ($method === self::REQUEST_POST || $method === self::REQUEST_PUT) {
140 1
                    $options['json'] = $parameters;
141 1
                }
142
            }
143 1
144 1
            return $this->client->request($method, self::BASE_API_URI . $uri, $options);
145
        }
146 1
        catch (ClientException $exception) {
147 1
            throw new LinodeException($exception->getResponse());
148
        }
149
        catch (GuzzleException) {
150 1
            throw new LinodeException(new Response(500));
151
        }
152
    }
153
}
154