Passed
Push — master ( faa861...d7c7ec )
by Will
05:37
created

AlmaApi::findUserById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 1
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace App\Service;
4
5
use GuzzleHttp\Client;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Psr\Log\LoggerInterface;
8
use SimpleXMLElement;
9
10
class AlmaApi
11
{
12
    private $logger;
13
14
    public function __construct(LoggerInterface $logger)
15
    {
16
        $this->logger = $logger;
17
    }
18
19
    /**
20
     * Wrapper for requests to Alma API
21
     *
22
     * @param $urlPath
23
     * @param $method
24
     * @param $requestParams
25
     * @param $templateParamNames
26
     * @param $templateParamValues
27
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
28
     * @throws GuzzleException
29
     */
30
    protected function executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues)
31
    {
32
        $client = new Client(['base_uri' => getenv('API_URL')]);
33
34
        $url = str_replace($templateParamNames, $templateParamValues, $urlPath);
35
        $defaultRequestParams = [
36
            'headers' => [
37
                'Authorization' => 'apikey ' . getenv('API_KEY'),
38
            ]
39
        ];
40
41
        try {
42
            $response = $client->request($method, $url, array_merge_recursive($requestParams, $defaultRequestParams));
43
        } catch (\Exception $e) {
44
            $emergency = true;
45
            $emergencyClientStatusCodes = ['404', '403', '401'];
46
            if ($e->hasResponse()) {
0 ignored issues
show
Bug introduced by
The method hasResponse() does not exist on Exception. It seems like you code against a sub-type of Exception such as GuzzleHttp\Exception\RequestException. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
            if ($e->/** @scrutinizer ignore-call */ hasResponse()) {
Loading history...
47
                $response = $e->getResponse();
0 ignored issues
show
Bug introduced by
The method getResponse() does not exist on Exception. It seems like you code against a sub-type of Exception such as GuzzleHttp\Exception\RequestException. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

47
                /** @scrutinizer ignore-call */ 
48
                $response = $e->getResponse();
Loading history...
48
                $statusCode = $response->getStatusCode();
49
                // 500 errors are always considered and emergency
50
                if (!in_array($statusCode, $emergencyClientStatusCodes) && !preg_match('/5[0-9][0-9]/', $statusCode)) {
51
                    $emergency = false;
52
                }
53
54
                $body = $response->getBody();
55
                try {
56
                    $sxml = new SimpleXMLElement($body);
57
58
                    foreach ($sxml->errorList as $error) {
59
                        $code = $error->error->errorCode;
60
                        $msg = $error->error->errorMessage;
61
                        $this->logger->error("Alma API error (HTTP status code: $statusCode Alma Error Code: $code): $msg");
62
                    }
63
                } catch (\Exception $e1) {
64
                    /**
65
                     *  The Alma API will return a 400 status code in the event that the API key is invalid.
66
                     *  Unfortunately, this same status code is returned under many other circumstances, for
67
                     *  example if a user provides incorrect credentials to log in.  The only way I can figure
68
                     *  out how to distinguish the two is by checking the actual text of the body, which annoyingly
69
                     *  isn't a valid XML response like all the other responses.
70
                     */
71
                    if ($body == 'Invalid API Key') {
72
                        $this->logger->emergency("@web-irt-dev Critical Error: $body :fire:");
73
                    } else {
74
                        $this->logger->error("Unable to parse response from Alma API as XML.  Status code: $statusCode  Body: $body");
75
                    }
76
                }
77
            }
78
79
            if ($emergency) {
80
                $this->logger->emergency("@web-irt-dev Critical Error: Unable to reach the Alma API! :fire:");
81
            }
82
83
            throw $e;
84
        }
85
86
        return $response;
87
    }
88
89
    /**
90
     * Get the users list of fees from Alma
91
     *
92
     * @param $userId
93
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
94
     * @throws GuzzleException
95
     */
96
    public function getUserFees($userId)
97
    {
98
        $method = 'GET';
99
        $urlPath = '/almaws/v1/users/{user_id}/fees';
100
        $templateParamNames = array('{user_id}');
101
        $templateParamValues = array(rawurlencode($userId));
102
        $query = [
103
            'user_id_type' => 'all_unique',
104
            'status' => 'ACTIVE'
105
        ];
106
        $requestParams = compact('query');
107
108
        return $this->executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues);
109
    }
110
111
    /**
112
     * Get the user from alma by the user id. Returns 400 status code if user does not exist.
113
     *
114
     * @param $userId
115
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
116
     * @throws GuzzleException
117
     */
118
    public function getUserById($userId)
119
    {
120
        $method = 'GET';
121
        $urlPath = '/almaws/v1/users/{user_id}';
122
        $templateParamNames = array('{user_id}');
123
        $templateParamValues = array(rawurlencode($userId));
124
        $query = [
125
            'user_id_type' => 'all_unique',
126
            'view' => 'full',
127
            'expand' => 'none'
128
        ];
129
        $requestParams = compact('query');
130
131
        return $this->executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues);
132
    }
133
134
    /**
135
     * @param string $userId The alphanumeric userId of the logged in user
136
     * @param string $feeId The Alma specific fee id to be updated
137
     * @param $amount
138
     * @param string $method
139
     * @param null $externalTransactionId
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $externalTransactionId is correct as it would always require null to be passed?
Loading history...
140
     * @param null $comment
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $comment is correct as it would always require null to be passed?
Loading history...
141
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
142
     * @throws GuzzleException
143
     */
144
    public function payUserFee($userId, $feeId, $amount, $method = 'ONLINE', $externalTransactionId = null, $comment = null)
145
    {
146
        $queryParams = [
147
            'op' => 'pay',
148
            'amount' => $amount,
149
            'method' => $method,
150
            'external_transaction_id' => $externalTransactionId,
151
            'comment' => $comment,
152
        ];
153
        /**
154
         * " If no callback is supplied, all entries of array equal to FALSE (see converting to boolean) will be removed."
155
         * - http://php.net/array_filter
156
         */
157
        $queryParams = array_filter($queryParams);
158
159
        return $this->updateUserFee($userId, $feeId, $queryParams);
160
    }
161
162
    /**
163
     * @param string $userId The alphanumeric userId of the logged in user
164
     * @param string $feeId The Alma specific fee id to be updated
165
     * @param array $query The parameters for the query.
166
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
167
     * @throws GuzzleException
168
     */
169
    protected function updateUserFee($userId, $feeId, $query)
170
    {
171
        $method = 'POST';
172
        $urlPath = '/almaws/v1/users/{user_id}/fees/{fee_id}';
173
        $templateParamNames = array('{user_id}', '{fee_id}');
174
        $templateParamValues = array(rawurlencode($userId), rawurlencode($feeId));
175
        $requestParams = compact('query');
176
177
        return $this->executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues);
178
    }
179
180
    /**
181
     * @param string $userId The alphanumeric userId of the logged in user
182
     * @param mixed $body A plain PHP object representing a fee.
183
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
184
     * @throws GuzzleException
185
     */
186
    public function createUserFee($userId, $body)
187
    {
188
        $method = 'POST';
189
        $urlPath = '/almaws/v1/users/{user_id}/fees';
190
        $templateParamNames = array('{user_id}');
191
        $templateParamValues = array(rawurlencode($userId));
192
193
        $headers = [
194
            'Content-Type' => 'application/json'
195
        ];
196
        $body = json_encode($body);
197
        $requestParams = compact('body', 'headers');
198
199
        return $this->executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues);
200
    }
201
202
    /**
203
     * @param string $userId The alphanumeric userId of the logged in user
204
     * @param string $userPassword The alphanumeric userPassword of the logged in user
205
     * @return mixed|null|\Psr\Http\Message\ResponseInterface
206
     * @throws GuzzleException
207
     */
208
    public function authenticateUser($userId, $userPassword)
209
    {
210
        $method = 'POST';
211
        $urlPath = '/almaws/v1/users/{user_id}';
212
        $templateParamNames = array('{user_id}');
213
        $templateParamValues = array(rawurlencode($userId));
214
        $query = [
215
            'user_id_type' => 'all_unique',
216
            'op' => 'auth'
217
        ];
218
219
        $headers = [
220
            'Exl-User-Pw' => $userPassword
221
        ];
222
        $requestParams = compact('query', 'headers');
223
224
        return $this->executeApiRequest($urlPath, $method, $requestParams, $templateParamNames, $templateParamValues);
225
    }
226
}
227