Completed
Push — master ( 32dc91...8fb626 )
by Byron
02:02
created

MicrosoftTranslator::getAccessToken()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
ccs 16
cts 16
cp 1
rs 9.0856
cc 3
eloc 15
nc 4
nop 0
crap 3
1
<?php
2
namespace badams\MicrosoftTranslator;
3
4
use badams\MicrosoftTranslator\Exceptions\ArgumentException;
5
use badams\MicrosoftTranslator\Exceptions\AuthException;
6
use badams\MicrosoftTranslator\Exceptions\QuotaExceededException;
7
use badams\MicrosoftTranslator\Exceptions\RecoverableException;
8
use badams\MicrosoftTranslator\Exceptions\TokenExpiredException;
9
use badams\MicrosoftTranslator\Exceptions\TranslatorException;
10
use GuzzleHttp\Exception\RequestException;
11
12
/**
13
 * Class MicrosoftTranslator
14
 * @package badams\MicrosoftTranslator
15
 */
16
class MicrosoftTranslator
17
{
18
    /**
19
     *
20
     */
21
    const AUTH_URL = 'https://datamarket.accesscontrol.windows.net/v2/OAuth2-13';
22
23
    /**
24
     *
25
     */
26
    const BASE_URL = 'http://api.microsofttranslator.com/V2/Http.svc/';
27
28
    /**
29
     * @var Client
30
     */
31
    private $http;
32
33
    /**
34
     * @var string
35
     */
36
    private $scope = 'http://api.microsofttranslator.com';
37
38
    /**
39
     * @var string
40
     */
41
    private $grantType = 'client_credentials';
42
43
    /**
44
     * @var string
45
     */
46
    private $clientId;
47
48
    /**
49
     * @var string
50
     */
51
    private $clientSecret;
52
53
    /**
54
     * @var string
55
     */
56
    private $accessToken;
57
58
    /**
59
     * MicrosoftTranslator constructor.
60
     */
61 24
    public function __construct(\GuzzleHttp\ClientInterface $httpClient = null)
62
    {
63 24
        if (is_null($httpClient)) {
64 3
            $httpClient = new \GuzzleHttp\Client();
65 3
        }
66
67 24
        $this->http = $httpClient;
0 ignored issues
show
Documentation Bug introduced by
It seems like $httpClient of type object<GuzzleHttp\ClientInterface> is incompatible with the declared type object<badams\MicrosoftTranslator\Client> of property $http.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
68 24
    }
69
70
    /**
71
     * @param $id
72
     * @param $secret
73
     */
74 9
    public function setClient($id, $secret)
75
    {
76 9
        $this->clientId = $id;
77 9
        $this->clientSecret = $secret;
78 9
    }
79
80
    /**
81
     * @return mixed
82
     * @throws AuthException
83
     */
84 18
    private function getAccessToken()
85
    {
86 18
        if (!$this->accessToken) {
87 18
            $params = array_merge([
88 18
                'grant_type' => $this->grantType,
89 18
                'scope' => $this->scope,
90 18
                'client_id' => $this->clientId,
91 18
                'client_secret' => $this->clientSecret
92 18
            ]);
93
94
            try {
95 18
                $response = $this->http->post(self::AUTH_URL, ['body' => $params]);
96 15
                $result = json_decode((string)$response->getBody());
97 18
            } catch (RequestException $e) {
98 3
                $result = json_decode((string)$e->getResponse()->getBody());
99 3
                throw new AuthException($result->error_description);
100
            }
101
102 15
            $this->accessToken = $result->access_token;
103 15
        }
104
105 15
        return $this->accessToken;
106
    }
107
108
    /**
109
     * @param $action
110
     * @param $params
111
     * @param string $method
112
     * @return null|string
113
     * @throws ArgumentException
114
     * @throws AuthException
115
     */
116 15
    private function request($action, $params, $method = 'GET')
117
    {
118 15
        $request = $this->http->createRequest($method, self::BASE_URL . $action, [
119 15
            'exceptions' => false,
120
            'headers' => [
121 15
                'Authorization' => 'Bearer ' . $this->getAccessToken(),
122 15
                'Content-Type' => 'text/xml',
123 15
            ],
124 15
            'query' => $params,
125 15
        ]);
126
127 15
        $response = $this->http->send($request);
128 15
        $result = (string)$response->getBody();
129
130 15
        if ($response->getStatusCode() == 200) {
131 6
            $xml = (array)simplexml_load_string($result);
132 6
            return (string)$xml[0];
133
        }
134
135
        try {
136 12
            $this->processError(strip_tags($result));
137 12
        } catch (TokenExpiredException $e) {
138 3
            $this->accessToken = null;
139 3
            return $this->request($action, $params, $method);
140
        }
141
142 3
        throw new TranslatorException($result);
143
    }
144
145
    /**
146
     * @param string $message
147
     * @throws ArgumentException
148
     * @throws QuotaExceededException
149
     * @throws TokenExpiredException
150
     * @throws TranslatorException
151
     */
152 12
    private function processError($message)
153
    {
154 12
        if (strpos($message, 'Argument Exception') === 0 && strpos($message, 'The incoming token has expired.')) {
155 3
            throw new TokenExpiredException($message);
156
        }
157
158 9
        if (strpos($message, 'TranslateApiException') === 0 && strpos($message, 'credentials has zero balance.')) {
159 3
            throw new QuotaExceededException($message);
160
        }
161
162 6
        if (strpos($message, 'Argument Exception') === 0) {
163 3
            throw new ArgumentException($message);
164
        }
165 3
    }
166
167
    /**
168
     * @param $text
169
     * @param $to
170
     * @param $from
171
     * @return mixed
172
     */
173 15
    public function translate($text, $to, $from)
174
    {
175 15
        return $this->request('Translate', [
176 15
            'to' => $to,
177 15
            'from' => $from,
178 15
            'text' => $text,
179 15
        ]);
180
    }
181
}