DeCaptchaBase::requestCode()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace jumper423\decaptcha\core;
4
5
/**
6
 * Распознавание капчи.
7
 *
8
 * Class DeCaptchaBase
9
 */
10
class DeCaptchaBase extends DeCaptchaAbstract implements DeCaptchaInterface
11
{
12
    const ACTION_RECOGNIZE = 1;
13
    const ACTION_UNIVERSAL = 2;
14
    const ACTION_UNIVERSAL_WITH_CAPTCHA = 3;
15
16
    const ACTION_FIELD_METHOD = 1;
17
    const ACTION_FIELD_KEY = 2;
18
    const ACTION_FIELD_FILE = 3;
19
    const ACTION_FIELD_PHRASE = 4;
20
    const ACTION_FIELD_REGSENSE = 5;
21
    const ACTION_FIELD_NUMERIC = 6;
22
    const ACTION_FIELD_MIN_LEN = 7;
23
    const ACTION_FIELD_MAX_LEN = 8;
24
    const ACTION_FIELD_LANGUAGE = 9;
25
    const ACTION_FIELD_SOFT_ID = 10;
26
    const ACTION_FIELD_CAPTCHA_ID = 11;
27
    const ACTION_FIELD_ACTION = 12;
28
    const ACTION_FIELD_QUESTION = 13;
29
    const ACTION_FIELD_CALC = 14;
30
    const ACTION_FIELD_HEADER_ACAO = 15;
31
    const ACTION_FIELD_INSTRUCTIONS = 16;
32
    const ACTION_FIELD_PINGBACK = 17;
33
    const ACTION_FIELD_TASK = 18;
34
    const ACTION_FIELD_IS_RUSSIAN = 19;
35
    const ACTION_FIELD_LABEL = 20;
36
    const ACTION_FIELD_GOOGLEKEY = 21;
37
    const ACTION_FIELD_RECAPTCHA = 22;
38
    const ACTION_FIELD_PROXY = 22;
39
    const ACTION_FIELD_PROXYTYPE = 23;
40
    const ACTION_FIELD_PAGEURL = 24;
41
    const ACTION_FIELD_GOOGLETOKEN = 25;
42
    const ACTION_FIELD_PROXYLOGIN = 26;
43
    const ACTION_FIELD_PROXYPASS = 27;
44
    const ACTION_FIELD_USERAGENT = 28;
45
    const ACTION_FIELD_COOKIES = 29;
46
    const ACTION_FIELD_PROXYPORT = 30;
47
    const ACTION_FIELD_COORDINATE = 31;
48
    const ACTION_FIELD_INVISIBLE = 32;
49
    const ACTION_FIELD_SSC_USER_ID = 33;
50
    const ACTION_FIELD_SSC_SESSION_ID = 34;
51
    const ACTION_FIELD_SSC_WEB_SERVER_SIGN = 35;
52
    const ACTION_FIELD_SSC_WEB_SERVER_SIGN2 = 36;
53
    const ACTION_FIELD_NOJS = 37;
54
    const ACTION_FIELD_PUBLICKEY = 38;
55
    const ACTION_FIELD_LANG = 39;
56
    const ACTION_FIELD_VERSION = 40;
57
    const ACTION_FIELD_MIN_SCORE = 41;
58
    const ACTION_FIELD_GT = 42;
59
    const ACTION_FIELD_CHALLENGE = 43;
60
    const ACTION_FIELD_API_SERVER = 44;
61
62
    const RESPONSE_RECOGNIZE_OK = 'OK';
63
    const RESPONSE_RECOGNIZE_REPEAT = 'ERROR_NO_SLOT_AVAILABLE';
64
    const RESPONSE_GET_OK = 'OK';
65
    const RESPONSE_GET_REPEAT = 'CAPCHA_NOT_READY';
66
67
    const SLEEP_RECOGNIZE = 5;
68
    const SLEEP_GET = 2;
69
    const SLEEP_BETWEEN = 5;
70
71
    const DECODE_ACTION_RECOGNIZE = 1;
72
    const DECODE_ACTION_GET = 2;
73
    const DECODE_ACTION_UNIVERSAL = 3;
74
75
    const DECODE_PARAM_RESPONSE = 1;
76
    const DECODE_PARAM_CAPTCHA = 2;
77
    const DECODE_PARAM_CODE = 3;
78
79
    public $actions = [
80
        self::ACTION_RECOGNIZE              => [],
81
        self::ACTION_UNIVERSAL              => [],
82
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => [],
83
    ];
84
85
    protected $decodeSettings = [
86
        self::DECODE_FORMAT => self::RESPONSE_TYPE_STRING,
87
        self::DECODE_ACTION => [
88
            self::DECODE_ACTION_RECOGNIZE => [],
89
            self::DECODE_ACTION_GET       => [],
90
        ],
91
    ];
92
93
    protected $limitSettings = [
94
        self::ACTION_RECOGNIZE              => 5,
95
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => 40,
96
    ];
97
98
    /**
99
     * @var DeCaptchaWiki
100
     */
101
    protected $wiki;
102
103
    /**
104
     * DeCaptchaBase constructor.
105
     *
106
     * @param $params
107
     */
108
    public function __construct($params)
109
    {
110
        $this->setParams($params);
111
        $this->wiki = new DeCaptchaWiki($this);
112
        $this->init();
113
    }
114
115
    public function init()
116
    {
117
    }
118
119
    /**
120
     * @param $filePath
121
     * @param array $additionally
122
     *
123
     * @throws DeCaptchaErrors
124
     *
125
     * @return bool
126
     */
127
    public function recognize($filePath, $additionally = [])
128
    {
129
        try {
130
            $this->resetLimits();
131
            if ($filePath) {
132
                $additionally[static::ACTION_FIELD_FILE] = $filePath;
133
            }
134
            $this->setParams($additionally);
135
136
            return $this->requestRecognize() && $this->requestCode();
137
        } catch (DeCaptchaErrors $e) {
138
            if ($this->causeAnError) {
139
                throw $e;
140
            }
141
            $this->errorObject = $e;
142
143
            return false;
144
        }
145
    }
146
147
    /**
148
     * Запуск распознавания капчи.
149
     *
150
     * @deprecated
151
     *
152
     * @param string $filePath Путь до файла или ссылка на него
153
     *
154
     * @return bool
155
     */
156
    public function run($filePath)
157
    {
158
        return $this->recognize($filePath);
159
    }
160
161
    /**
162
     * Универсальная отправка повторяющихся запросов.
163
     *
164
     * @param int      $action
165
     * @param int      $decodeAction
166
     * @param int      $setParam
167
     * @param int      $decodeSerParam
168
     * @param int      $ok
169
     * @param int      $sleep
170
     * @param int      $repeat
171
     * @param int|null $error
172
     *
173
     * @throws DeCaptchaErrors
174
     *
175
     * @return bool
176
     */
177
    protected function requestRepeat($action, $decodeAction, $setParam, $decodeSerParam, $ok, $sleep, $repeat, $error = null)
178
    {
179
        if (is_null($error)) {
180
            $error = static::DECODE_PARAM_RESPONSE;
181
        }
182
        while ($this->limitHasNotYetEnded($action)) {
183
            $this->executionDelayed($sleep);
184
            $response = $this->getResponse($action);
185
            $dataRecognize = $this->decodeResponse($decodeAction, $response);
186
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $ok && !empty($dataRecognize[$decodeSerParam])) {
187
                $this->setParam($setParam, $dataRecognize[$decodeSerParam]);
188
                $this->executionDelayed(static::SLEEP_BETWEEN);
189
190
                return true;
191
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === $repeat) {
192
                continue;
193
            }
194
195
            throw new DeCaptchaErrors($dataRecognize[$error], null, $this->errorLang);
196
        }
197
198
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT, null, $this->errorLang);
199
    }
200
201
    /**
202
     * Универсальная отправка.
203
     *
204
     * @param string $action
205
     *
206
     * @return array
207
     */
208
    protected function requestUniversal($action)
209
    {
210
        $this->setParam(static::ACTION_FIELD_ACTION, $action);
211
        $response = $this->getResponse(static::ACTION_UNIVERSAL);
212
213
        return $this->decodeResponse(static::DECODE_ACTION_UNIVERSAL, $response);
214
    }
215
216
    /**
217
     * @throws DeCaptchaErrors
218
     *
219
     * @return bool
220
     */
221
    protected function requestRecognize()
222
    {
223
        return $this->requestRepeat(static::ACTION_RECOGNIZE, static::DECODE_ACTION_RECOGNIZE, static::PARAM_SPEC_CAPTCHA, static::DECODE_PARAM_CAPTCHA, static::RESPONSE_RECOGNIZE_OK, static::SLEEP_RECOGNIZE, static::RESPONSE_RECOGNIZE_REPEAT);
224
    }
225
226
    /**
227
     * @throws DeCaptchaErrors
228
     *
229
     * @return bool
230
     */
231
    protected function requestCode()
232
    {
233
        return $this->requestRepeat(static::ACTION_UNIVERSAL_WITH_CAPTCHA, static::DECODE_ACTION_GET, static::PARAM_SPEC_CODE, static::DECODE_PARAM_CODE, static::RESPONSE_GET_OK, static::SLEEP_GET, static::RESPONSE_GET_REPEAT);
234
    }
235
236
    /**
237
     * @return array|string
238
     */
239
    public function getCode()
240
    {
241
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    public function getError()
248
    {
249
        return $this->errorObject->getMessage();
250
    }
251
252
    /**
253
     * @param bool $causeAnError
254
     */
255
    public function setCauseAnError($causeAnError)
256
    {
257
        $this->causeAnError = $causeAnError;
258
    }
259
260
    public function getWiki($lang = 'en')
261
    {
262
        $this->wiki->setLang($lang);
263
264
        return $this->wiki;
265
    }
266
}
267