Completed
Push — master ( 570f1a...76d1b8 )
by Владислав
02:10
created

DeCaptchaBase::run()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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 = 0;
13
    const ACTION_UNIVERSAL = 1;
14
    const ACTION_UNIVERSAL_WITH_CAPTCHA = 2;
15
16
    const ACTION_FIELD_METHOD = 0;
17
    const ACTION_FIELD_KEY = 1;
18
    const ACTION_FIELD_FILE = 2;
19
    const ACTION_FIELD_PHRASE = 3;
20
    const ACTION_FIELD_REGSENSE = 4;
21
    const ACTION_FIELD_NUMERIC = 5;
22
    const ACTION_FIELD_MIN_LEN = 6;
23
    const ACTION_FIELD_MAX_LEN = 7;
24
    const ACTION_FIELD_LANGUAGE = 8;
25
    const ACTION_FIELD_SOFT_ID = 9;
26
    const ACTION_FIELD_CAPTCHA_ID = 10;
27
    const ACTION_FIELD_ACTION = 11;
28
    const ACTION_FIELD_QUESTION = 12;
29
    const ACTION_FIELD_CALC = 13;
30
    const ACTION_FIELD_HEADER_ACAO = 14;
31
    const ACTION_FIELD_TEXTINSTRUCTIONS = 15;
32
    const ACTION_FIELD_PINGBACK = 16;
33
34
    const RESPONSE_RECOGNIZE_OK = 'OK';
35
    const RESPONSE_RECOGNIZE_REPEAT = 'ERROR_NO_SLOT_AVAILABLE';
36
    const RESPONSE_GET_OK = 'OK';
37
    const RESPONSE_GET_REPEAT = 'CAPCHA_NOT_READY';
38
39
    const SLEEP_RECOGNIZE = 5;
40
    const SLEEP_GET = 2;
41
    const SLEEP_BETWEEN = 5;
42
43
    const DECODE_ACTION_RECOGNIZE = 0;
44
    const DECODE_ACTION_GET = 1;
45
46
    const DECODE_PARAM_RESPONSE = 0;
47
    const DECODE_PARAM_CAPTCHA = 1;
48
    const DECODE_PARAM_CODE = 2;
49
50
    protected $paramsNames = [
51
        self::ACTION_FIELD_METHOD           => 'method',
52
        self::ACTION_FIELD_KEY              => 'key',
53
        self::ACTION_FIELD_FILE             => 'file',
54
        self::ACTION_FIELD_PHRASE           => 'phrase',
55
        self::ACTION_FIELD_REGSENSE         => 'regsense',
56
        self::ACTION_FIELD_NUMERIC          => 'numeric',
57
        self::ACTION_FIELD_MIN_LEN          => 'min_len',
58
        self::ACTION_FIELD_MAX_LEN          => 'max_len',
59
        self::ACTION_FIELD_LANGUAGE         => 'language',
60
        self::ACTION_FIELD_SOFT_ID          => 'soft_id',
61
        self::ACTION_FIELD_CAPTCHA_ID       => 'id',
62
        self::ACTION_FIELD_ACTION           => 'action',
63
        self::ACTION_FIELD_QUESTION         => 'question',
64
        self::ACTION_FIELD_HEADER_ACAO      => 'header_acao',
65
        self::ACTION_FIELD_TEXTINSTRUCTIONS => 'textinstructions',
66
        self::ACTION_FIELD_PINGBACK         => 'pingback',
67
    ];
68
69
    protected $actions = [
70
        self::ACTION_RECOGNIZE => [
71
            self::ACTION_URI    => 'in.php',
72
            self::ACTION_METHOD => self::ACTION_METHOD_POST,
73
            self::ACTION_FIELDS => [
74
                self::ACTION_FIELD_METHOD => [
75
                    self::PARAM_SLUG_DEFAULT => 'post',
76
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
77
                ],
78
                self::ACTION_FIELD_KEY => [
79
                    self::PARAM_SLUG_REQUIRE => true,
80
                    self::PARAM_SLUG_SPEC    => self::PARAM_SPEC_KEY,
81
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
82
                ],
83
                self::ACTION_FIELD_FILE => [
84
                    self::PARAM_SLUG_REQUIRE => true,
85
                    self::PARAM_SLUG_SPEC    => self::PARAM_SPEC_FILE,
86
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
87
                ],
88
                self::ACTION_FIELD_PHRASE => [
89
                    self::PARAM_SLUG_DEFAULT => 0,
90
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
91
                ],
92
                self::ACTION_FIELD_REGSENSE => [
93
                    self::PARAM_SLUG_DEFAULT => 0,
94
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
95
                ],
96
                self::ACTION_FIELD_NUMERIC => [
97
                    self::PARAM_SLUG_DEFAULT => 0,
98
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
99
                ],
100
                self::ACTION_FIELD_MIN_LEN => [
101
                    self::PARAM_SLUG_DEFAULT => 0,
102
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
103
                ],
104
                self::ACTION_FIELD_MAX_LEN => [
105
                    self::PARAM_SLUG_DEFAULT => 0,
106
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
107
                ],
108
                self::ACTION_FIELD_LANGUAGE => [
109
                    self::PARAM_SLUG_DEFAULT => 0,
110
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
111
                ],
112
                self::ACTION_FIELD_QUESTION => [
113
                    self::PARAM_SLUG_DEFAULT => 0,
114
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
115
                ],
116
                self::ACTION_FIELD_CALC => [
117
                    self::PARAM_SLUG_DEFAULT => 0,
118
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
119
                ],
120
                self::ACTION_FIELD_HEADER_ACAO => [
121
                    self::PARAM_SLUG_DEFAULT => 0,
122
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
123
                ],
124
                self::ACTION_FIELD_TEXTINSTRUCTIONS => [
125
                    self::PARAM_SLUG_TYPE => self::PARAM_FIELD_TYPE_STRING,
126
                ],
127
                self::ACTION_FIELD_PINGBACK => [
128
                    self::PARAM_SLUG_TYPE => self::PARAM_FIELD_TYPE_STRING,
129
                ],
130
                self::ACTION_FIELD_SOFT_ID => [
131
                    self::PARAM_SLUG_VARIABLE => false,
132
                    self::PARAM_SLUG_TYPE     => self::PARAM_FIELD_TYPE_INTEGER,
133
                ],
134
            ],
135
        ],
136
        self::ACTION_UNIVERSAL => [
137
            self::ACTION_URI    => 'res.php',
138
            self::ACTION_METHOD => self::ACTION_METHOD_GET,
139
            self::ACTION_FIELDS => [
140
                self::ACTION_FIELD_KEY => [
141
                    self::PARAM_SLUG_REQUIRE => true,
142
                    self::PARAM_SLUG_SPEC    => self::PARAM_SPEC_KEY,
143
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
144
                ],
145
                self::ACTION_FIELD_ACTION => [
146
                    self::PARAM_SLUG_REQUIRE => true,
147
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
148
                ],
149
                self::ACTION_FIELD_HEADER_ACAO => [
150
                    self::PARAM_SLUG_DEFAULT => 0,
151
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
152
                ],
153
            ],
154
        ],
155
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => [
156
            self::ACTION_URI    => 'res.php',
157
            self::ACTION_METHOD => self::ACTION_METHOD_GET,
158
            self::ACTION_FIELDS => [
159
                self::ACTION_FIELD_KEY => [
160
                    self::PARAM_SLUG_REQUIRE => true,
161
                    self::PARAM_SLUG_SPEC    => self::PARAM_SPEC_KEY,
162
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
163
                ],
164
                self::ACTION_FIELD_CAPTCHA_ID => [
165
                    self::PARAM_SLUG_REQUIRE => true,
166
                    self::PARAM_SLUG_SPEC    => self::PARAM_SPEC_CAPTCHA,
167
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
168
                ],
169
                self::ACTION_FIELD_ACTION => [
170
                    self::PARAM_SLUG_REQUIRE => true,
171
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_STRING,
172
                ],
173
                self::ACTION_FIELD_HEADER_ACAO => [
174
                    self::PARAM_SLUG_DEFAULT => 0,
175
                    self::PARAM_SLUG_TYPE    => self::PARAM_FIELD_TYPE_INTEGER,
176
                ],
177
            ],
178
        ],
179
    ];
180
181
    protected $decodeSettings = [
182
        self::DECODE_FORMAT => self::RESPONSE_TYPE_STRING,
183
        self::DECODE_ACTION => [
184
            self::DECODE_ACTION_RECOGNIZE => [
185
                self::DECODE_SEPARATOR => '|',
186
                self::DECODE_PARAMS    => [
187
                    self::DECODE_PARAM_RESPONSE => [
188
                        self::DECODE_PARAM_SETTING_MARKER => 0,
189
                    ],
190
                    self::DECODE_PARAM_CAPTCHA => [
191
                        self::DECODE_PARAM_SETTING_MARKER => 1,
192
                    ],
193
                ],
194
            ],
195
            self::DECODE_ACTION_GET => [
196
                self::DECODE_SEPARATOR => '|',
197
                self::DECODE_PARAMS    => [
198
                    self::DECODE_PARAM_RESPONSE => [
199
                        self::DECODE_PARAM_SETTING_MARKER => 0,
200
                    ],
201
                    self::DECODE_PARAM_CODE => [
202
                        self::DECODE_PARAM_SETTING_MARKER => 1,
203
                    ],
204
                ],
205
            ],
206
        ],
207
    ];
208
209
    protected $limitSettings = [
210
        self::ACTION_RECOGNIZE              => 3,
211
        self::ACTION_UNIVERSAL_WITH_CAPTCHA => 20,
212
    ];
213
214
    public function __construct($params)
215
    {
216
        $this->setParams($params);
217
    }
218
219
    public function recognize($filePath)
220
    {
221
        try {
222
            $this->resetLimits();
223
            $this->setParamSpec(static::PARAM_SPEC_FILE, $this->getFilePath($filePath));
224
225
            return $this->requestRecognize() && $this->requestCode();
226
        } catch (DeCaptchaErrors $e) {
227
            if ($this->causeAnError) {
228
                throw $e;
229
            }
230
            $this->errorObject = $e;
231
232
            return false;
233
        }
234
    }
235
236
    /**
237
     * Запуск распознавания капчи.
238
     *
239
     * @deprecated
240
     *
241
     * @param string $filePath Путь до файла или ссылка на него
242
     *
243
     * @return bool
244
     */
245
    public function run($filePath)
246
    {
247
        return $this->recognize($filePath);
248
    }
249
250 View Code Duplication
    protected function requestRecognize()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
251
    {
252
        while ($this->limitHasNotYetEnded(static::ACTION_RECOGNIZE)) {
253
            $this->executionDelayed(static::SLEEP_RECOGNIZE);
254
            $response = $this->getResponse(static::ACTION_RECOGNIZE);
255
            $dataRecognize = $this->decodeResponse(static::DECODE_ACTION_RECOGNIZE, $response);
256
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_RECOGNIZE_OK && !empty($dataRecognize[static::DECODE_PARAM_CAPTCHA])) {
257
                $this->setParamSpec(static::PARAM_SPEC_CAPTCHA, $dataRecognize[static::DECODE_PARAM_CAPTCHA]);
258
                $this->executionDelayed(static::SLEEP_BETWEEN);
259
260
                return true;
261
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_RECOGNIZE_REPEAT) {
262
                continue;
263
            }
264
            throw new DeCaptchaErrors($dataRecognize[static::DECODE_PARAM_RESPONSE]);
265
        }
266
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
267
    }
268
269 View Code Duplication
    protected function requestCode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
    {
271
        while ($this->limitHasNotYetEnded(static::ACTION_UNIVERSAL_WITH_CAPTCHA)) {
272
            $this->executionDelayed(static::SLEEP_GET);
273
            $response = $this->getResponse(static::ACTION_UNIVERSAL_WITH_CAPTCHA);
274
            $dataGet = $this->decodeResponse(static::DECODE_ACTION_GET, $response);
275
            if ($dataGet[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_GET_OK && !empty($dataGet[static::DECODE_PARAM_CODE])) {
276
                $this->setParamSpec(static::PARAM_SPEC_CODE, $dataGet[static::DECODE_PARAM_CODE]);
277
278
                return true;
279
            } elseif ($dataGet[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_GET_REPEAT) {
280
                continue;
281
            }
282
            throw new DeCaptchaErrors($dataGet[static::DECODE_PARAM_RESPONSE]);
283
        }
284
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
285
    }
286
287
    public function getCode()
288
    {
289
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
290
    }
291
292
    public function getError()
293
    {
294
        return $this->errorObject->getMessage();
295
    }
296
}
297