Completed
Push — master ( bcf726...5504be )
by Rafał
49s
created

PaymentsHubAdapter   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 7
dl 0
loc 167
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
B getSubscriptions() 0 39 6
B getSubscription() 0 35 7
A buildQueryParams() 0 8 1
A send() 0 27 4
A getAuthToken() 0 16 1
A createSubscription() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Paywall Component.
7
 *
8
 * Copyright 2018 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2018 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Component\Paywall\Adapter;
18
19
use GuzzleHttp\ClientInterface;
20
use GuzzleHttp\Exception\RequestException;
21
use Psr\Http\Message\ResponseInterface;
22
use SWP\Component\Paywall\Factory\SubscriptionFactoryInterface;
23
use SWP\Component\Paywall\Model\SubscriberInterface;
24
use SWP\Component\Paywall\Model\SubscriptionInterface;
25
26
final class PaymentsHubAdapter extends AbstractPaywallAdapter
27
{
28
    public const API_ENDPOINT = '/public-api/v1/';
29
30
    public const API_AUTH_ENDPOINT = '/api/v1/login_check';
31
32
    public const ENDPOINT_SUBSCRIPTIONS = self::API_ENDPOINT.'subscriptions/';
33
34
    public const ACTIVE_SUBSCRIPTION_STATE = 'fulfilled';
35
36
    /**
37
     * @var array
38
     */
39
    private $config;
40
41
    /**
42
     * @var SubscriptionFactoryInterface
43
     */
44
    private $subscriptionFactory;
45
46
    /**
47
     * @var ClientInterface
48
     */
49
    private $client;
50
51
    public function __construct(array $config, SubscriptionFactoryInterface $subscriptionFactory, ClientInterface $client)
52
    {
53
        $this->config = $config;
54
        $this->subscriptionFactory = $subscriptionFactory;
55
        $this->client = $client;
56
    }
57
58
    public function getSubscriptions(SubscriberInterface $subscriber, array $filters = []): array
59
    {
60
        $newFilters = [];
61
        foreach ($filters as $key => $filter) {
62
            $newFilters['metadata.'.$key] = $filter;
63
        }
64
65
        $subscriptions = [];
66
        $newFilters['metadata.email'] = $subscriber->getSubscriberId();
67
68
        $url = sprintf('%s%s', self::ENDPOINT_SUBSCRIPTIONS, $this->buildQueryParams($newFilters));
69
70
        $response = $this->send($url);
71
72
        if (null === $response) {
73
            return [];
74
        }
75
76
        $subscriptionsData = \json_decode($response->getBody()->getContents(), true);
77
78
        if (!isset($subscriptionsData['_embedded']) && !isset($subscriptionsData['_embedded']['items'])) {
79
            return null;
80
        }
81
82
        $items = $subscriptionsData['_embedded']['items'];
83
84
        foreach ($items as $subscriptionData) {
85
            /** @var SubscriptionInterface $subscription */
86
            $subscription = $subscription = $this->createSubscription();
87
            $subscription->setId((string) $subscriptionData['id']);
88
            $subscription->setCode((string) $subscriptionData['id']);
89
            $subscription->setType($subscriptionData['type']);
90
            $subscription->setDetails($subscriptionData['metadata']);
91
92
            $subscriptions[] = $subscription;
93
        }
94
95
        return $subscriptions;
96
    }
97
98
    public function getSubscription(SubscriberInterface $subscriber, array $filters = []): ?SubscriptionInterface
99
    {
100
        $newFilters = [];
101
        foreach ($filters as $key => $filter) {
102
            $newFilters['metadata.'.$key] = $filter;
103
        }
104
105
        $filters['metadata.email'] = $subscriber->getSubscriberId();
106
107
        $url = sprintf('%s%s', self::ENDPOINT_SUBSCRIPTIONS, $this->buildQueryParams($newFilters));
108
109
        $response = $this->send($url);
110
111
        if (null === $response || (null !== $response && 404 === $response->getStatusCode())) {
112
            return null;
113
        }
114
115
        $subscriptionsData = \json_decode($response->getBody()->getContents(), true);
116
117
        if (!isset($subscriptionsData['_embedded']) && !isset($subscriptionsData['_embedded']['items'])) {
118
            return null;
119
        }
120
121
        $subscriptionData = $subscriptionsData['_embedded']['items'][0];
122
123
        /** @var SubscriptionInterface $subscription */
124
        $subscription = $this->createSubscription();
125
        $subscription->setId((string) $subscriptionData['id']);
126
        $subscription->setCode((string) $subscriptionData['id']);
127
        $subscription->setType($subscriptionData['type']);
128
        $subscription->setDetails($subscriptionData['metadata']);
129
        $subscription->setActive(self::ACTIVE_SUBSCRIPTION_STATE === $subscriptionData['state']);
130
131
        return $subscription;
132
    }
133
134
    private function buildQueryParams(array $filters = []): string
135
    {
136
        $criteria = [
137
            'criteria' => $filters,
138
        ];
139
140
        return '?'.http_build_query($criteria);
141
    }
142
143
    private function send(string $endpoint, array $data = [], array $requestOptions = []): ?ResponseInterface
144
    {
145
        if (empty($requestOptions)) {
146
            $requestOptions = [
147
                'headers' => [
148
                    'Content-Type' => 'application/json',
149
                ],
150
                'body' => $this->getJsonSerializer()->serialize($data, 'json'),
151
                'timeout' => 3,
152
            ];
153
        }
154
155
        if (isset($requestOptions['headers'])) {
156
            $requestOptions['headers']['Authorization'] = sprintf('Bearer %s', $this->getAuthToken());
157
        }
158
159
        $response = null;
160
161
        try {
162
            /** @var ResponseInterface $response */
163
            $response = $this->client->get($this->config['serverUrl'].$endpoint, $requestOptions);
164
        } catch (RequestException $requestException) {
165
            // ignore if request fails
166
        }
167
168
        return $response;
169
    }
170
171
    private function getAuthToken(): string
172
    {
173
        $requestOptions = [
174
            'body' => $this->getJsonSerializer()->serialize([
175
                'username' => $this->config['credentials']['username'],
176
                'password' => $this->config['credentials']['password'],
177
            ], 'json'),
178
        ];
179
180
        /** @var ResponseInterface $response */
181
        $response = $this->client->post($this->config['serverUrl'].self::API_AUTH_ENDPOINT, $requestOptions);
182
183
        $decodedResponse = \json_decode($response->getBody()->getContents(), true);
184
185
        return $decodedResponse['token'];
186
    }
187
188
    private function createSubscription(): SubscriptionInterface
189
    {
190
        return $this->subscriptionFactory->create();
191
    }
192
}
193