Completed
Push — master ( eac57c...9ff768 )
by Laurens
02:04
created

iZettleClient::validateAccessToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LauLamanApps\iZettleApi;
6
7
use DateTime;
8
use GuzzleHttp\Client as GuzzleClient;
9
use LauLamanApps\iZettleApi\API\Product\Category;
10
use LauLamanApps\iZettleApi\API\Product\Discount;
11
use LauLamanApps\iZettleApi\API\Product\Library;
12
use LauLamanApps\iZettleApi\API\Product\Product;
13
use LauLamanApps\iZettleApi\API\Purchase\PurchaseHistory;
14
use LauLamanApps\iZettleApi\Client\AccessToken;
15
use LauLamanApps\iZettleApi\Client\Exceptions\AccessTokenExpiredException;
16
use LauLamanApps\iZettleApi\Client\Product\CategoryParser;
17
use LauLamanApps\iZettleApi\Client\Product\DiscountParser;
18
use LauLamanApps\iZettleApi\Client\Product\LibraryParser;
19
use LauLamanApps\iZettleApi\Client\Product\ProductParser;
20
use LauLamanApps\iZettleApi\Client\Purchase\PurchaseHistoryParser;
21
use Psr\Http\Message\ResponseInterface;
22
23
final class iZettleClient
24
{
25
    /**
26
     * iZettle' PRODUCTS domain
27
     * API documentation https://products.izettle.com/swagger#/
28
     */
29
    const PRODUCT_BASE_URL = 'https://products.izettle.com';
30
    const PRODUCT_CATEGORY_ALL = self::PRODUCT_BASE_URL . '/organizations/%s/categories';
31
    const PRODUCT_CATEGORY_SINGLE = self::PRODUCT_CATEGORY_ALL . '/%s';
32
    const PRODUCT_DISCOUNT_ALL = self::PRODUCT_BASE_URL . '/organizations/%s/discounts';
33
    const PRODUCT_DISCOUNT_SINGLE = self::PRODUCT_DISCOUNT_ALL . '/%s';
34
    const PRODUCT_LIBRARY = self::PRODUCT_BASE_URL . '/organizations/%s/library';
35
    const PRODUCT_PRODUCTS_ALL = self::PRODUCT_BASE_URL . '/organizations/%s/products';
36
    const PRODUCT_PRODUCTS_SINGLE = self::PRODUCT_PRODUCTS_ALL . '/%s';
37
38
    /**
39
     * iZettle' Purchase domain
40
     * API documentation https://products.izettle.com/swagger#/
41
     */
42
    const PURCHASE_BASE_URL = 'https://purchase.izettle.com';
43
    const PURCHASE_HISTORY_URL = self::PURCHASE_BASE_URL . '/purchases/v2';
44
45
    private $guzzleClient;
46
    private $accessToken;
47
    private $organizationUuid = 'self';
48
49 12
    public function __construct(GuzzleClient $guzzleClient, AccessToken $accessToken)
50
    {
51 12
        $this->guzzleClient = $guzzleClient;
52 12
        $this->accessToken = $accessToken;
53 12
        $this->validateAccessToken();
54 11
    }
55
56 1
    public function setOrganizationUuid(int $organizationUuid): void
57
    {
58 1
        $this->organizationUuid = $organizationUuid;
0 ignored issues
show
Documentation Bug introduced by
The property $organizationUuid was declared of type string, but $organizationUuid is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
59 1
    }
60
61 1
    public function getCategories(): array
62
    {
63 1
        $url = sprintf(self::PRODUCT_CATEGORY_ALL, $this->organizationUuid);
64
65 1
        return CategoryParser::createFromResponse($this->get($url));
66
    }
67
68 1
    public function createCategory(Category $category): void
69
    {
70 1
        $url = sprintf(self::PRODUCT_CATEGORY_ALL, $this->organizationUuid);
71 1
        $this->post($url, $category->getCreateData());
72 1
    }
73
74 1
    public function getDiscounts(): array
75
    {
76 1
        $url = sprintf(self::PRODUCT_DISCOUNT_ALL, $this->organizationUuid);
77
78 1
        return DiscountParser::createFromResponse($this->get($url));
79
    }
80
81 1
    public function createDiscount(Discount $discount): void
82
    {
83 1
        $url = sprintf(self::PRODUCT_DISCOUNT_ALL, $this->organizationUuid);
84
85 1
        $this->post($url, $discount->getCreateData());
86 1
    }
87
88 1
    public function deleteDiscount(Discount $discount): void
89
    {
90 1
        $url = sprintf(self::PRODUCT_DISCOUNT_SINGLE, $this->organizationUuid, (string) $discount->getUuid());
91
92 1
        $this->delete($url);
93 1
    }
94
95 1
    public function getLibrary(): Library
96
    {
97 1
        $url = sprintf(self::PRODUCT_LIBRARY, $this->organizationUuid);
98
99 1
        return LibraryParser::createFromResponse($this->get($url));
100
    }
101
102 1
    public function getProducts(): array
103
    {
104 1
        $url = sprintf(self::PRODUCT_PRODUCTS_ALL, $this->organizationUuid);
105
106 1
        return ProductParser::createFromResponse($this->get($url));
107
    }
108
109 1
    public function createProduct(Product $product): void
110
    {
111 1
        $url = sprintf(self::PRODUCT_PRODUCTS_ALL, $this->organizationUuid);
112
113 1
        $this->post($url, $product->getCreateData());
114 1
    }
115
116 1
    public function deleteProduct(Product $product): void
117
    {
118 1
        $url = sprintf(self::PRODUCT_PRODUCTS_SINGLE, $this->organizationUuid, (string) $product->getUuid());
119
120 1
        $this->delete($url);
121 1
    }
122
123 1
    public function getPurchaseHistory(): PurchaseHistory
124
    {
125 1
        return PurchaseHistoryParser::createFromResponse($this->get(self::PURCHASE_HISTORY_URL));
126
    }
127
128 5
    private function get(string $url, ?array $queryParameters = null): ResponseInterface
129
    {
130 5
        $options =  array_merge(['headers' => $this->getAuthorizationHeader()], ['query' => $queryParameters]);
131
132 5
        return $this->guzzleClient->get($url, $options);
133
    }
134
135 3
    private function post(string $url, string $data): void
136
    {
137 3
        $headers = array_merge(
138 3
            $this->getAuthorizationHeader(),
139
            [
140 3
                'content-type' => 'application/json',
141
                'Accept' => 'application/json',
142
            ]
143
        );
144
145 3
        $options =  array_merge(['headers' => $headers], ['body' => $data]);
146
147 3
        $this->guzzleClient->post($url, $options);
148 3
    }
149
150 2
    private function delete(string $url): void
151
    {
152 2
        $this->guzzleClient->delete($url, ['headers' => $this->getAuthorizationHeader()]);
153 2
    }
154
155 12
    private function validateAccessToken(): void
156
    {
157 12
        if ($this->accessToken->isExpired()) {
158 1
            throw new AccessTokenExpiredException(
159 1
                sprintf(
160 1
                    'Access Token was valid till \'%s\' its now \'%s\'',
161 1
                    $this->accessToken->getExpires()->format('Y-m-d H:i:s.u'),
162 1
                    (new DateTime())->format('Y-m-d H:i:s.u')
163
                )
164
            );
165
        }
166 11
    }
167
168 10
    private function getAuthorizationHeader(): array
169
    {
170 10
        return ['Authorization' => sprintf('Bearer %s', $this->accessToken->getToken())];
171
    }
172
}
173