Completed
Push — master ( f323bf...0da584 )
by Byron
02:55
created

MicrosoftTranslator::setClient()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
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
    public function __construct(\GuzzleHttp\ClientInterface $httpClient = null)
62
    {
63
        if (is_null($httpClient)) {
64
            $httpClient = new \GuzzleHttp\Client();
65
        }
66
67
        $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
    }
69
70
    /**
71
     * @param $id
72
     * @param $secret
73
     */
74
    public function setClient($id, $secret)
75
    {
76
        $this->clientId = $id;
77
        $this->clientSecret = $secret;
78
    }
79
80
    /**
81
     * @return mixed
82
     * @throws AuthException
83
     */
84
    private function updateAccessToken()
85
    {
86
        $params = array_merge([
87
            'grant_type' => $this->grantType,
88
            'scope' => $this->scope,
89
            'client_id' => $this->clientId,
90
            'client_secret' => $this->clientSecret
91
        ]);
92
93
        try {
94
            $response = $this->http->post(self::AUTH_URL, ['body' => $params]);
95
            $result = json_decode((string)$response->getBody());
96
        } catch (RequestException $e) {
97
            $result = json_decode((string)$e->getResponse()->getBody());
98
            throw new AuthException($result->error_description);
99
        }
100
101
        $this->accessToken = $result->access_token;
102
    }
103
104
    /**
105
     * @param $action
106
     * @param $params
107
     * @param string $method
108
     * @return null|string
109
     * @throws ArgumentException
110
     * @throws AuthException
111
     */
112
    private function request($action, $params, $method = 'GET')
113
    {
114
        if (!$this->accessToken) {
115
            $this->updateAccessToken();
116
        }
117
118
        $request = $this->http->createRequest($method, self::BASE_URL . $action, [
119
            'exceptions' => false,
120
            'headers' => [
121
                'Authorization' => 'Bearer ' . $this->accessToken,
122
                'Content-Type' => 'text/xml',
123
            ],
124
            'query' => $params,
125
        ]);
126
127
        $response = $this->http->send($request);
128
        $result = (string)$response->getBody();
129
130
        if ($response->getStatusCode() == 200) {
131
            $xml = (array)simplexml_load_string($result);
132
            return (string)$xml[0];
133
        }
134
135
        try {
136
            $this->processError(strip_tags($result));
137
        } catch (TokenExpiredException $e) {
138
            $this->accessToken = null;
139
            return $this->request($action, $params, $method);
140
        }
141
142
        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
    private function processError($message)
153
    {
154
        if (strpos($message, 'Argument Exception') === 0 && strpos($message, 'The incoming token has expired.')) {
155
            throw new TokenExpiredException($message);
156
        }
157
158
        if (strpos($message, 'TranslateApiException') === 0 && strpos($message, 'credentials has zero balance.')) {
159
            throw new QuotaExceededException($message);
160
        }
161
162
        if (strpos($message, 'Argument Exception') === 0) {
163
            throw new ArgumentException($message);
164
        }
165
    }
166
167
    /**
168
     * @param $text
169
     * @param $to
170
     * @param $from
171
     * @return mixed
172
     */
173
    public function translate($text, $to, $from)
174
    {
175
        return $this->request('Translate', [
176
            'to' => $to,
177
            'from' => $from,
178
            'text' => $text,
179
        ]);
180
    }
181
}