Test Failed
Push — master ( 53d82e...9a7f3b )
by Mehmet
02:15
created

Client::actionFactory()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 3
nop 3
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
/**
4
 * @package MerchantSafeUnipay\SDK
5
 * @author Mehmet Korkmaz <[email protected]>
6
 * @licence https://opensource.org/licenses/mit-license.php MIT
7
 *
8
 * Documentation can be found at https://merchantsafeunipay.com/msu/api/v2/doc
9
 */
10
11
namespace MerchantSafeUnipay\SDK;
12
13
use GuzzleHttp;
14
use GuzzleHttp\Client as GuzzleClient;
15
use MerchantSafeUnipay\SDK\Environment\EnvironmentInterface as Environment;
16
use Psr\Http\Message\ResponseInterface;
17
use Psr\Log\LoggerInterface;
18
use MerchantSafeUnipay\SDK\Action\ActionInterface;
19
use Psr7\Http\Message\RequestInterface;
20
use MerchantSafeUnipay\SDK\Exception\InvalidArgumentException;
21
use MerchantSafeUnipay\SDK\Exception\BadMethodCallException;
22
use MerchantSafeUnipay\SDK\Exception\RequestException;
23
24
class Client
25
{
26
    /**
27
     *
28
     */
29
    const MSU_API_VERSION = 2;
30
31
    /**
32
     * @var array
33
     */
34
    private static $validActions = [
35
36
        'session',
37
        'financialTransactions',
38
        'approveActions',
39
        'rejectActions',
40
        'dealer',
41
        'dealerPST',
42
        'dealerType',
43
        'eWallet',
44
        'merchant',
45
        'merchantUser',
46
        'merchantContent',
47
        'messageContent',
48
        'payByLinkPayment',
49
        'paymentPolicy',
50
        'paymentSystem',
51
        'paymentType',
52
        'recurringPayment',
53
        'recurringPlan',
54
        'recurringPlanCard'
55
    ];
56
57
    private static $validQueryActions = [
58
        'Transaction',
59
        'DealerTransaction',
60
        'SubDealerTransaction',
61
        'Installment',
62
        'Card',
63
        'CardExpiry',
64
        'Customer',
65
        'Session',
66
        'PayByLinkPayment',
67
        'Bin',
68
        'Campaign',
69
        'OnlineCampaign',
70
        'RecurringPlan',
71
        'PaymentSystems',
72
        'MerchantPaymentSystems',
73
        'MerchantProfile',
74
        'PaymentSystemData',
75
        'Points',
76
        'PaymentPolicy',
77
        'SplitPayment',
78
        'Merchant',
79
        'MerchantContent',
80
        'MerchantStatusHistory',
81
        'MerchantUser',
82
        'UserRolePermission',
83
        'Dealer',
84
        'DealerType',
85
        'DealerPst',
86
        'DealerStatusHistory',
87
        'MerchantUserDealers',
88
        'Groups',
89
        'ExecutiveReport',
90
        'TransactionRule'
91
    ];
92
93
    /**
94
     * @var Environment
95
     */
96
    private $environment;
97
    /**
98
     * @var GuzzleClient
99
     */
100
    private $guzzleClient;
101
102
    private $logger;
103
104
    private static $headers = [
105
        'User-Agent' => 'MerchantSafeUnipayPhpSDK/1.0',
106
        'Accept'     => 'application/json'
107
    ];
108
109
    /**
110
     * @var array
111
     */
112
    private static $possibleResponses = [
0 ignored issues
show
Unused Code introduced by
The property $possibleResponses is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
113
        '00' => 'Approved',
114
        '01' => 'Waiting for Approval',
115
        '98' => 'General Error',
116
        '99' => 'Declined'
117
    ];
118
119
    /**
120
     * Client constructor.
121
     * @param Environment $environment
122
     * @param GuzzleClient $guzzleClient
123
     * @param LoggerInterface $logger
124
     */
125
    public function __construct(Environment $environment, GuzzleClient $guzzleClient, LoggerInterface $logger)
126
    {
127
        $this->environment = $environment;
128
        $this->guzzleClient = $guzzleClient;
129
        $this->logger = $logger;
130
    }
131
132
    /**
133
     * @param $name
134
     * @param $arguments
135
     * @throws BadMethodCallException
136
     * @throws RequestException
137
     * @throws InvalidArgumentException
138
     * @return array
139
     */
140
    public function __call(string $name, array $arguments)
141
    {
142
        return $this->requestAction($this->getCallAction($name, $arguments));
143
    }
144
145
    /**
146
     * @param $name
147
     * @param $arguments
148
     * @throws BadMethodCallException
149
     * @throws RequestException
150
     * @throws InvalidArgumentException
151
     * @return array
152
     */
153
    public function query(string $name, array $arguments)
154
    {
155
        return $this->requestAction($this->getQueryAction($name, $arguments));
156
    }
157
158
    private function getCallAction(string $name, array $arguments)
159
    {
160
        $namespace = '\\MerchantSafeUnipay\\SDK\\Action';
161
        $actionClass =  $namespace . '\\'. ucfirst($name);
162 View Code Duplication
        if (!in_array($name, self::$validActions, true) || !class_exists($actionClass)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
            $message = sprintf('%s is not valid MerchantSafeUnipay API action.', $name);
164
            throw new BadMethodCallException($message);
165
        }
166
        return $this->actionFactory($name, $arguments, $namespace);
167
    }
168
    private function getQueryAction(string $name, array $arguments)
169
    {
170
        $name = str_replace(' ', '', ucwords(str_replace('_', '', $name)));
171
        $namespace = '\\MerchantSafeUnipay\\SDK\\Action\\Query';
172
        $actionClass =  $namespace . '\\'. ucfirst($name);
173 View Code Duplication
        if (!in_array($name, self::$validQueryActions, true) || !class_exists($actionClass)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
174
            $message = sprintf('%s is not valid MerchantSafeUnipay API query action.', $name);
175
            throw new BadMethodCallException($message);
176
        }
177
        return $this->actionFactory($name, ['getQuery', $arguments], $namespace);
178
    }
179
180
    /**
181
     * @param string $name
182
     * @param array $arguments
183
     * @param string $namespace
184
     * @return ActionInterface
185
     * @throws BadMethodCallException
186
     * @throws InvalidArgumentException
187
     */
188
    private function actionFactory(string $name, array $arguments, string $namespace)
189
    {
190
        $actionClass =  $namespace . '\\'. ucfirst($name);
191
        $actionName = $arguments[0];
192
        $actionObject = new $actionClass($this->environment->getMerchantData());
193
        if (!method_exists($actionObject, $actionName)) {
194
            $message = sprintf(
195
                '%s/%s is not valid MerchantSafeUnipay API action.',
196
                ucfirst($name),
197
                ucfirst($actionName)
198
            );
199
            throw new BadMethodCallException($message);
200
        }
201
        try {
202
            $actionObject->$actionName($arguments[1]);
203
            return $actionObject;
204
        } catch (TypeError $e) {
0 ignored issues
show
Bug introduced by
The class MerchantSafeUnipay\SDK\TypeError does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
205
            $message = 'This action needs arguments, no argument provided.';
206
            throw new InvalidArgumentException($message);
207
        }
208
    }
209
210
    private function requestAction(ActionInterface $action)
211
    {
212
        $headers = array_merge(self::$headers, $action->getHeaders());
213
        $response = $this->httpRequest($action->getAction(), $headers, $action->getQueryParams());
214
215
        return [
216
            'status' => $response->getStatusCode(),
217
            'reason' => $response->getReasonPhrase(),
218
            'headers' => $response->getHeaders(),
219
            'data' => json_decode((string) $response->getBody(), true)
220
        ];
221
    }
222
223
    /**
224
     * @param string $actionName
225
     * @param array $headers
226
     * @param array  $queryParams
227
     * @throws RequestException
228
     * @return ResponseInterface
229
     */
230
    private function httpRequest(string $actionName, array $headers, array $queryParams)
231
    {
232
        $uri = $this->environment->getUrl();
233
        $queryParams['ACTION'] = $actionName;
234
        $options = [
235
            'headers' => $headers,
236
            'form_params' => $queryParams
237
        ];
238
        try {
239
            return $this->guzzleClient->post($uri, $options);
240
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class MerchantSafeUnipay\SDK\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
241
            $message =   $e->getMessage();
242
        }
243
        $message = sprintf('MerchantSafe Unipay API Request Error:% s', $message);
244
        throw new RequestException($message);
245
    }
246
}
247