Completed
Push — master ( f22af2...cb0170 )
by Dmitry
02:01
created

Client::getPingbacks()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 12
nc 3
nop 0
1
<?php
2
3
namespace Rucaptcha;
4
5
use Rucaptcha\Exception\ErrorResponseException;
6
7
/**
8
 * Class Client
9
 *
10
 * @package Rucaptcha
11
 * @author Dmitry Gladyshev <[email protected]>
12
 */
13
class Client extends GenericClient
14
{
15
    const STATUS_OK_REPORT_RECORDED = 'OK_REPORT_RECORDED';
16
17
    /**
18
     * @var string
19
     */
20
    protected $serverBaseUri = 'http://rucaptcha.com';
21
22
    /**
23
     * Your application ID in Rucaptcha catalog.
24
     * The value `1013` is ID of this library. Set in false if you want to turn off sending any ID.
25
     *
26
     * @see https://rucaptcha.com/software/view/php-api-client
27
     * @var string
28
     */
29
    protected $softId = '1013';
30
31
    /**
32
     * @inheritdoc
33
     */
34
    public function sendCaptcha($content, array $extra = [])
35
    {
36
        if ($this->softId && !isset($extra[Extra::SOFT_ID])) {
37
            $extra[Extra::SOFT_ID] = $this->softId;
38
        }
39
        return parent::sendCaptcha($content, $extra);
40
    }
41
42
    /**
43
     * Bulk captcha result.
44
     *
45
     * @param int[] $captchaIds         # Captcha task Ids array
46
     * @return string[]                 # Array $captchaId => $captchaText or false if is not ready
47
     * @throws ErrorResponseException
48
     */
49
    public function getCaptchaResultBulk(array $captchaIds)
50
    {
51
        $response = $this->getHttpClient()->request('GET', '/res.php?' . http_build_query([
52
                'key' => $this->apiKey,
53
                'action' => 'get',
54
                'ids' => join(',', $captchaIds)
55
            ]));
56
57
        $captchaTexts = $response->getBody()->__toString();
58
59
        $this->getLogger()->info("Got bulk response: `{$captchaTexts}`.");
60
61
        $captchaTexts = explode("|", $captchaTexts);
62
63
        $result = [];
64
65
        foreach ($captchaTexts as $index => $captchaText) {
66
            $captchaText = html_entity_decode(trim($captchaText));
67
            $result[$captchaIds[$index]] =
68
                ($captchaText == self::STATUS_CAPTCHA_NOT_READY) ? false : $captchaText;
69
        }
70
71
        return $result;
72
    }
73
74
    /**
75
     * Returns balance of account.
76
     *
77
     * @return string
78
     */
79
    public function getBalance()
80
    {
81
        $response = $this
82
            ->getHttpClient()
83
            ->request('GET', "/res.php?key={$this->apiKey}&action=getbalance");
84
85
        return $response->getBody()->__toString();
86
    }
87
88
    /**
89
     * Report of wrong recognition.
90
     *
91
     * @param string $captchaId
92
     * @return bool
93
     * @throws ErrorResponseException
94
     */
95
    public function badCaptcha($captchaId)
96
    {
97
        $response = $this
98
            ->getHttpClient()
99
            ->request('GET', "/res.php?key={$this->apiKey}&action=reportbad&id={$captchaId}");
100
101
        $responseText = $response->getBody()->__toString();
102
103
        if ($responseText === self::STATUS_OK_REPORT_RECORDED) {
104
            return true;
105
        }
106
107
        throw new ErrorResponseException(
108
            $this->getErrorMessage($responseText) ?: $responseText,
109
            $this->getErrorCode($responseText) ?: 0
110
        );
111
    }
112
113
    /**
114
     * Returns server health data.
115
     *
116
     * @param string|string[] $paramsList   # List of metrics to be returned
117
     * @return array                        # Array of load metrics $metric => $value formatted
118
     */
119
    public function getLoad($paramsList = ['waiting', 'load', 'minbid', 'averageRecognitionTime'])
120
    {
121
        $parser = $this->getLoadXml();
122
123
        if (is_string($paramsList)) {
124
            return $parser->$paramsList->__toString();
125
        }
126
127
        $statusData = [];
128
129
        foreach ($paramsList as $item) {
130
            $statusData[$item] = $parser->$item->__toString();
131
        }
132
133
        return $statusData;
134
    }
135
136
    /**
137
     * Returns load data as XML.
138
     *
139
     * @return \SimpleXMLElement
140
     */
141
    public function getLoadXml()
142
    {
143
        $response = $this
144
            ->getHttpClient()
145
            ->request('GET', "/load.php");
146
147
        return new \SimpleXMLElement($response->getBody()->__toString());
148
    }
149
150
    /**
151
     * @param string $captchaId     # Captcha task ID
152
     * @return array | false        # Solved captcha and cost array or false if captcha is not ready
153
     * @throws ErrorResponseException
154
     */
155
    public function getCaptchaResultWithCost($captchaId)
156
    {
157
        $response = $this
158
            ->getHttpClient()
159
            ->request('GET', "/res.php?key={$this->apiKey}&action=get2&id={$captchaId}");
160
161
        $responseText = $response->getBody()->__toString();
162
163
        if ($responseText === self::STATUS_CAPTCHA_NOT_READY) {
164
            return false;
165
        }
166
167
        if (strpos($responseText, 'OK|') !== false) {
168
            $this->getLogger()->info("Got OK response: `{$responseText}`.");
169
            $data = explode('|', $responseText);
170
            return [
171
                'captcha' => html_entity_decode(trim($data[1])),
172
                'cost' => html_entity_decode(trim($data[2])),
173
            ];
174
        }
175
176
        throw new ErrorResponseException(
177
            $this->getErrorMessage($responseText) ?: $responseText,
178
            $this->getErrorCode($responseText) ?: 0
179
        );
180
    }
181
182
    /**
183
     * Add pingback url to rucaptcha whitelist.
184
     *
185
     * @param string $url
186
     * @return bool                     # true if added and exception if fail
187
     * @throws ErrorResponseException
188
     */
189
    public function addPingback($url)
190
    {
191
        $response = $this
192
            ->getHttpClient()
193
            ->request('GET', "/res.php?key={$this->apiKey}&action=add_pingback&addr={$url}");
194
195
        $responseText = $response->getBody()->__toString();
196
197
        if ($responseText === self::STATUS_OK) {
198
            return true;
199
        }
200
201
        throw new ErrorResponseException(
202
            $this->getErrorMessage($responseText) ?: $responseText,
203
            $this->getErrorCode($responseText) ?: 0
204
        );
205
    }
206
207
    /**
208
     * Returns pingback whitelist items.
209
     *
210
     * @return string[]                 # List of urls
211
     * @throws ErrorResponseException
212
     */
213
    public function getPingbacks()
214
    {
215
        $response = $this
216
            ->getHttpClient()
217
            ->request('GET', "/res.php?key={$this->apiKey}&action=get_pingback");
218
219
        $responseText = $response->getBody()->__toString();
220
221
        if (strpos($responseText, 'OK|') !== false) {
222
            $data = explode('|', $responseText);
223
            unset($data[0]);
224
            return empty($data[1]) ? [] : array_values($data);
225
        }
226
227
        throw new ErrorResponseException(
228
            $this->getErrorMessage($responseText) ?: $responseText,
229
            $this->getErrorCode($responseText) ?: 0
230
        );
231
    }
232
233
    /**
234
     * Remove pingback url from whitelist.
235
     *
236
     * @param string $uri
237
     * @return bool
238
     * @throws ErrorResponseException
239
     */
240
    public function deletePingback($uri)
241
    {
242
        $response = $this
243
            ->getHttpClient()
244
            ->request('GET', "/res.php?key={$this->apiKey}&action=del_pingback&addr={$uri}");
245
246
        $responseText = $response->getBody()->__toString();
247
248
        if ($responseText === self::STATUS_OK) {
249
            return true;
250
        }
251
        throw new ErrorResponseException(
252
            $this->getErrorMessage($responseText) ?: $responseText,
253
            $this->getErrorCode($responseText) ?: 0
254
        );
255
    }
256
257
    /**
258
     * Truncate pingback whitelist.
259
     *
260
     * @return bool
261
     * @throws ErrorResponseException
262
     */
263
    public function deleteAllPingbacks()
264
    {
265
        return $this->deletePingback('all');
266
    }
267
268
    /**
269
     * Match error code by response.
270
     *
271
     * @param string $responseText
272
     * @return int
273
     */
274
    private function getErrorCode($responseText)
275
    {
276
        if (preg_match('/ERROR:\s*(\d{0,4})/ui', $responseText, $matches)) {
277
            return intval($matches[1]);
278
        }
279
        return 0;
280
    }
281
}
282