Completed
Push — master ( 2a8373...bfc208 )
by Andreas
03:38
created

AbstractResource::handleResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 4
Metric Value
c 6
b 1
f 4
dl 0
loc 11
rs 9.4285
cc 1
eloc 6
nc 1
nop 1
1
<?php
2
/**
3
 * EveryPay PHP Library
4
 */
5
6
namespace Everypay;
7
8
use Everypay\Http\Client\CurlClient;
9
use Everypay\Http\Client\ClientInterface;
10
use Everypay\Exception\ApiErrorException;
11
12
/**
13
 * Common methods for all API resources.
14
 */
15
abstract class AbstractResource
16
{
17
    private static $client;
18
19
    private static $actions = array(
20
        'create',
21
        'capture',
22
        'retrieve',
23
        'listAll',
24
        'refund',
25
        'update',
26
        'delete'
27
    );
28
29
    private static $resources = array(
30
        'tokens',
31
        'payments',
32
        'customers',
33
        'notifications'
34
    );
35
36
    private static $clientOptions = array();
37
38
    /**
39
     * Create a new resource object.
40
     * See Resource class for more input info.
41
     *
42
     * @param array $params
43
     * @return stdClass
44
     */
45
    public static function create(array $params)
46
    {
47
        return self::invoke(__FUNCTION__, static::RESOURCE_NAME, $params);
48
    }
49
50
    /**
51
     * Retrieve an existing resource based on its token.
52
     *
53
     * @param string|stdClass $token A valid resource token returned from a
54
     *                               successful resource creation.
55
     * @return stdClass
56
     */
57
    public static function retrieve($token)
58
    {
59
        $params = array('token_id' => $token);
60
61
        return self::invoke(__FUNCTION__, static::RESOURCE_NAME, $params);
62
    }
63
64
    /**
65
     * Get a collection of given resource objects by applying some filters.
66
     * Filters are optionals and include:
67
     * - count:     The number of objects to returns. Availabe range is 1 - 20.
68
     * - offset:    The offset of collection to return. Useful for pagination.
69
     * - date_from: Return objects that created after that date.
70
     *              Format: YYYY-mm-dd
71
     * - date_to:   Return objects that created before that date.
72
     *              Format: YYYY-mm-dd
73
     *
74
     * @param array $filters Filter options.
75
     * @return stdClass
76
     */
77
    public static function listAll(array $filters = array())
78
    {
79
        return self::invoke(__FUNCTION__, static::RESOURCE_NAME, $filters);
80
    }
81
82
    /**
83
     * Update an existing resource.
84
     *
85
     * @param string|stdClass $token
86
     * @param array $params
87
     * @return stdClass
88
     */
89
    public static function update($token, array $params)
90
    {
91
        $params['token_id'] = $token;
92
93
        return self::invoke(__FUNCTION__, static::RESOURCE_NAME, $params);
94
    }
95
96
    /**
97
     * Delete a resource.
98
     *
99
     * @param string|stdClass $token
100
     * @return stdClass
101
     */
102
    public static function delete($token, array $params = array())
103
    {
104
        $params = array_merge($params, array('token_id' => $token));
105
106
        return self::invoke(__FUNCTION__, static::RESOURCE_NAME, $params);
107
    }
108
109
    public static function setClientOption($option, $value)
110
    {
111
        self::$clientOptions[$option] = $value;
112
    }
113
114
    public static function setClient(ClientInterface $client)
115
    {
116
        self::$client = $client;
117
    }
118
119
    public static function resetClient()
120
    {
121
        self::$client = null;
122
    }
123
124
    protected static function invoke($action, $resourceName, array $params = array())
125
    {
126
        if (!in_array($action, self::$actions)) {
127
            throw new Exception\InvalidArgumentException(sprintf("Action `%s` does not exists", $action));
128
        }
129
130
        if (!in_array($resourceName, self::$resources)) {
131
            throw new Exception\InvalidArgumentException(sprintf("Resource `%s` does not exists", $resourceName));
132
        }
133
134
        $options = array(
135
            'resource' => $resourceName,
136
            'api_key'  => Everypay::getApiKey(),
137
            'api_uri'  => Everypay::getApiUrl(),
138
        );
139
140
        $options = array_merge($params, $options);
141
        $actionClass = 'Everypay\\Action\\' . (ucwords($action));
142
        $actionInstance = new $actionClass($options);
143
        $request = $actionInstance();
144
145
        return self::handleResponse(self::createClient()->send($request));
146
    }
147
148
    private static function createClient()
149
    {
150
        $client = self::$client ?: new CurlClient(self::$clientOptions);
151
        $client->setOption(CurlClient::TIMEOUT, 30);
152
        $client->setOption(CurlClient::USER_AGENT, 'EveryPay PHP Library ' . Everypay::VERSION);
153
154
        return $client;
155
    }
156
157
    /**
158
     * Handle API response.
159
     *
160
     * @param \Everypay\Http\ResponseInterface $response
161
     * @return \stdClass
162
     * @throws \Everypay\Exception\ApiErrorException
163
     */
164
    protected static function handleResponse($response)
165
    {
166
        self::resolveContentType($response);
167
168
        $body = $response->getBody();
169
        $response = json_decode($body);
170
171
        self::resolveErrorResponse($response);
172
173
        return $response;
174
    }
175
176
    private static function resolveContentType($response)
177
    {
178
        $contentType = $response->getHeaderLine('Content-Type');
179
        if (stripos($contentType, 'application/json') === false) {
180
            throw new Exception\CurlException(
181
                'The returned response is not in json format'
182
            );
183
        }
184
    }
185
186
    private static function resolveErrorResponse($response)
187
    {
188
        if (isset($response->error->code)
189
            && EveryPay::throwExceptions()
190
        ) {
191
            throw new ApiErrorException(
192
                $response->error->message,
193
                $response->error->code
194
            );
195
        }
196
    }
197
}
198