Completed
Push — master ( d1e8ce...92efb6 )
by Владислав
02:21
created

DeCaptchaBase::limitHasNotYetEnded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
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 recognize($filePath, $rr)
215
    {
216
        try {
217
            $this->resetLimits();
218
            $this->setParamSpec(static::PARAM_SPEC_FILE, $this->getFilePath($filePath));
219
220
            return $this->requestRecognize() && $this->requestCode();
221
        } catch (DeCaptchaErrors $e) {
222
            if ($this->causeAnError) {
223
                throw $e;
224
            }
225
            $this->errorObject = $e;
226
            return false;
227
        }
228
    }
229
230 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...
231
    {
232
        while ($this->limitHasNotYetEnded(static::ACTION_RECOGNIZE)) {
233
            $this->executionDelayed(static::SLEEP_RECOGNIZE);
234
            $response = $this->getResponse(static::ACTION_RECOGNIZE);
235
            $dataRecognize = $this->decodeResponse(static::DECODE_ACTION_RECOGNIZE, $response);
236
            if ($dataRecognize[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_RECOGNIZE_OK && !empty($dataRecognize[static::DECODE_PARAM_CAPTCHA])) {
237
                $this->setParamSpec(static::PARAM_SPEC_CAPTCHA, $dataRecognize[static::DECODE_PARAM_CAPTCHA]);
238
                $this->executionDelayed(static::SLEEP_BETWEEN);
239
240
                return true;
241
            } elseif ($dataRecognize[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_RECOGNIZE_REPEAT) {
242
                continue;
243
            }
244
            throw new DeCaptchaErrors($dataRecognize[static::DECODE_PARAM_RESPONSE]);
245
        }
246
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
247
    }
248
249 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...
250
    {
251
        while ($this->limitHasNotYetEnded(static::ACTION_UNIVERSAL_WITH_CAPTCHA)) {
252
            $this->executionDelayed(static::SLEEP_GET);
253
            $response = $this->getResponse(static::ACTION_UNIVERSAL_WITH_CAPTCHA);
254
            $dataGet = $this->decodeResponse(static::DECODE_ACTION_GET, $response);
255
            if ($dataGet[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_GET_OK && !empty($dataGet[static::DECODE_PARAM_CODE])) {
256
                $this->setParamSpec(static::PARAM_SPEC_CODE, $dataGet[static::DECODE_PARAM_CODE]);
257
                return true;
258
            } elseif ($dataGet[static::DECODE_PARAM_RESPONSE] === static::RESPONSE_GET_REPEAT) {
259
                continue;
260
            }
261
            throw new DeCaptchaErrors($dataGet[static::DECODE_PARAM_RESPONSE]);
262
        }
263
        throw new DeCaptchaErrors(DeCaptchaErrors::ERROR_LIMIT);
264
    }
265
266
    public function getCode()
267
    {
268
        return $this->getParamSpec(static::PARAM_SPEC_CODE);
269
    }
270
271
    public function getError()
272
    {
273
        return $this->errorObject->getMessage();
274
    }
275
}
276